@oxyhq/services 22.12.4 → 22.12.7

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 (639) hide show
  1. package/README.md +16 -46
  2. package/lib/commonjs/index.js +84 -10
  3. package/lib/commonjs/index.js.map +1 -1
  4. package/lib/commonjs/notifications/deviceNotifications.js +380 -0
  5. package/lib/commonjs/notifications/deviceNotifications.js.map +1 -0
  6. package/lib/commonjs/ui/boot/runProviderColdBoot.js +51 -9
  7. package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
  8. package/lib/commonjs/ui/client.js +0 -13
  9. package/lib/commonjs/ui/client.js.map +1 -1
  10. package/lib/commonjs/ui/components/AvatarCameraBadge.js +3 -2
  11. package/lib/commonjs/ui/components/AvatarCameraBadge.js.map +1 -1
  12. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +14 -3
  13. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
  14. package/lib/commonjs/ui/components/OxyAuthChooser.js +70 -1121
  15. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  16. package/lib/commonjs/ui/components/OxyConsentScreen.js +50 -12
  17. package/lib/commonjs/ui/components/OxyConsentScreen.js.map +1 -1
  18. package/lib/commonjs/ui/components/OxyProvider.js +4 -4
  19. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  20. package/lib/commonjs/ui/components/OxySignInButton.js +74 -40
  21. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
  22. package/lib/commonjs/ui/components/OxySignInRequestSurface.js +147 -0
  23. package/lib/commonjs/ui/components/OxySignInRequestSurface.js.map +1 -0
  24. package/lib/commonjs/ui/components/ProfileButton.js +4 -3
  25. package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
  26. package/lib/commonjs/ui/components/SettingsIcon.js +3 -2
  27. package/lib/commonjs/ui/components/SettingsIcon.js.map +1 -1
  28. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +527 -0
  29. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -0
  30. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +90 -0
  31. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +1 -0
  32. package/lib/commonjs/ui/components/authChooser/SignInRequestView.js +106 -0
  33. package/lib/commonjs/ui/components/authChooser/SignInRequestView.js.map +1 -0
  34. package/lib/commonjs/ui/components/authChooser/SignUpView.js +188 -0
  35. package/lib/commonjs/ui/components/authChooser/SignUpView.js.map +1 -0
  36. package/lib/commonjs/ui/components/authChooser/TroubleDisclosure.js +61 -0
  37. package/lib/commonjs/ui/components/authChooser/TroubleDisclosure.js.map +1 -0
  38. package/lib/commonjs/ui/components/authChooser/primitives.js +170 -0
  39. package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -0
  40. package/lib/commonjs/ui/components/authChooser/requestSurfaces.js +153 -0
  41. package/lib/commonjs/ui/components/authChooser/requestSurfaces.js.map +1 -0
  42. package/lib/commonjs/ui/components/authChooser/signInProgress.js +54 -0
  43. package/lib/commonjs/ui/components/authChooser/signInProgress.js.map +1 -0
  44. package/lib/commonjs/ui/components/{oxyAuthChooserStyles.js → authChooser/styles.js} +19 -1
  45. package/lib/commonjs/ui/components/authChooser/styles.js.map +1 -0
  46. package/lib/commonjs/ui/components/authChooser/types.js +70 -0
  47. package/lib/commonjs/ui/components/authChooser/types.js.map +1 -0
  48. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js +50 -0
  49. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js.map +1 -0
  50. package/lib/commonjs/ui/components/fileManagement/AnimatedButton.js +3 -2
  51. package/lib/commonjs/ui/components/fileManagement/AnimatedButton.js.map +1 -1
  52. package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js +3 -2
  53. package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
  54. package/lib/commonjs/ui/components/fileManagement/FileViewer.js +15 -14
  55. package/lib/commonjs/ui/components/fileManagement/FileViewer.js.map +1 -1
  56. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js +6 -5
  57. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
  58. package/lib/commonjs/ui/components/modals/DeleteAccountModal.js +3 -2
  59. package/lib/commonjs/ui/components/modals/DeleteAccountModal.js.map +1 -1
  60. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js +6 -6
  61. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  62. package/lib/commonjs/ui/components/payment/PaymentMethodStep.js +5 -5
  63. package/lib/commonjs/ui/components/payment/PaymentMethodStep.js.map +1 -1
  64. package/lib/commonjs/ui/components/payment/PaymentReviewStep.js +10 -9
  65. package/lib/commonjs/ui/components/payment/PaymentReviewStep.js.map +1 -1
  66. package/lib/commonjs/ui/components/payment/PaymentSuccessStep.js +4 -3
  67. package/lib/commonjs/ui/components/payment/PaymentSuccessStep.js.map +1 -1
  68. package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js +6 -5
  69. package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js.map +1 -1
  70. package/lib/commonjs/ui/context/OxyContext.js +200 -29
  71. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  72. package/lib/commonjs/ui/context/commitSessionFlow.js +43 -0
  73. package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -1
  74. package/lib/commonjs/ui/context/useOxyAccountGraph.js +13 -5
  75. package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
  76. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +6 -1
  77. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +1 -1
  78. package/lib/commonjs/ui/index.js +0 -13
  79. package/lib/commonjs/ui/index.js.map +1 -1
  80. package/lib/commonjs/ui/oauth/browserAuthTransport.js +168 -0
  81. package/lib/commonjs/ui/oauth/browserAuthTransport.js.map +1 -0
  82. package/lib/commonjs/ui/oauth/completeOAuthCode.js +78 -0
  83. package/lib/commonjs/ui/oauth/completeOAuthCode.js.map +1 -0
  84. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js +48 -0
  85. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js.map +1 -0
  86. package/lib/commonjs/ui/oauth/oauthHandshake.js +53 -0
  87. package/lib/commonjs/ui/oauth/oauthHandshake.js.map +1 -0
  88. package/lib/commonjs/ui/oauth/oauthPopup.js +229 -0
  89. package/lib/commonjs/ui/oauth/oauthPopup.js.map +1 -0
  90. package/lib/commonjs/ui/oauth/oauthPopupMessages.js +141 -0
  91. package/lib/commonjs/ui/oauth/oauthPopupMessages.js.map +1 -0
  92. package/lib/commonjs/ui/oauth/types.js +2 -0
  93. package/lib/commonjs/ui/oauth/types.js.map +1 -0
  94. package/lib/commonjs/ui/screens/AccountMembersScreen.js +4 -3
  95. package/lib/commonjs/ui/screens/AccountMembersScreen.js.map +1 -1
  96. package/lib/commonjs/ui/screens/CreateAccountScreen.js +7 -6
  97. package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
  98. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +4 -3
  99. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  100. package/lib/commonjs/ui/screens/FAQScreen.js +3 -2
  101. package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
  102. package/lib/commonjs/ui/screens/FeedbackScreen.js +11 -10
  103. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  104. package/lib/commonjs/ui/screens/FileManagementScreen.js +19 -18
  105. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  106. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +4 -3
  107. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  108. package/lib/commonjs/ui/screens/ManageAccountScreen.js +2 -2
  109. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  110. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +3 -3
  111. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  112. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +9 -8
  113. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  114. package/lib/commonjs/ui/screens/ProfileScreen.js +10 -10
  115. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  116. package/lib/commonjs/ui/screens/UserListScreen.js +3 -3
  117. package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
  118. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +3 -2
  119. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  120. package/lib/commonjs/ui/screens/fileManagement/FileLibraryError.js +4 -3
  121. package/lib/commonjs/ui/screens/fileManagement/FileLibraryError.js.map +1 -1
  122. package/lib/commonjs/ui/screens/fileManagement/FileListSection.js +4 -3
  123. package/lib/commonjs/ui/screens/fileManagement/FileListSection.js.map +1 -1
  124. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +4 -3
  125. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  126. package/lib/commonjs/ui/screens/fileManagement/UploadBar.js +3 -2
  127. package/lib/commonjs/ui/screens/fileManagement/UploadBar.js.map +1 -1
  128. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +3 -2
  129. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  130. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +4 -3
  131. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  132. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +4 -3
  133. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  134. package/lib/commonjs/ui/server.js +2 -5
  135. package/lib/commonjs/ui/server.js.map +1 -1
  136. package/lib/commonjs/ui/session/authStore.js +6 -75
  137. package/lib/commonjs/ui/session/authStore.js.map +1 -1
  138. package/lib/commonjs/ui/session/createSessionClient.js +11 -3
  139. package/lib/commonjs/ui/session/createSessionClient.js.map +1 -1
  140. package/lib/commonjs/ui/session/identityBinding.js +95 -0
  141. package/lib/commonjs/ui/session/identityBinding.js.map +1 -0
  142. package/lib/commonjs/ui/session/index.js +13 -0
  143. package/lib/commonjs/ui/session/index.js.map +1 -1
  144. package/lib/commonjs/ui/session/nativeSecureStorage.js +90 -0
  145. package/lib/commonjs/ui/session/nativeSecureStorage.js.map +1 -0
  146. package/lib/commonjs/ui/session/tokenTransport.js +11 -1
  147. package/lib/commonjs/ui/session/tokenTransport.js.map +1 -1
  148. package/lib/commonjs/ui/utils/crossOriginRestore.js +3 -2
  149. package/lib/commonjs/ui/utils/crossOriginRestore.js.map +1 -1
  150. package/lib/commonjs/ui/utils/deliveryPlatform.js +58 -0
  151. package/lib/commonjs/ui/utils/deliveryPlatform.js.map +1 -0
  152. package/lib/commonjs/ui/utils/oauthReturn.js +70 -46
  153. package/lib/commonjs/ui/utils/oauthReturn.js.map +1 -1
  154. package/lib/module/index.js +27 -4
  155. package/lib/module/index.js.map +1 -1
  156. package/lib/module/notifications/deviceNotifications.js +371 -0
  157. package/lib/module/notifications/deviceNotifications.js.map +1 -0
  158. package/lib/module/ui/boot/runProviderColdBoot.js +51 -9
  159. package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
  160. package/lib/module/ui/client.js +0 -1
  161. package/lib/module/ui/client.js.map +1 -1
  162. package/lib/module/ui/components/AvatarCameraBadge.js +1 -1
  163. package/lib/module/ui/components/AvatarCameraBadge.js.map +1 -1
  164. package/lib/module/ui/components/OxyAccountDialogScreen.js +14 -3
  165. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
  166. package/lib/module/ui/components/OxyAuthChooser.js +74 -1126
  167. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  168. package/lib/module/ui/components/OxyConsentScreen.js +50 -12
  169. package/lib/module/ui/components/OxyConsentScreen.js.map +1 -1
  170. package/lib/module/ui/components/OxyProvider.js +4 -4
  171. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  172. package/lib/module/ui/components/OxySignInButton.js +76 -42
  173. package/lib/module/ui/components/OxySignInButton.js.map +1 -1
  174. package/lib/module/ui/components/OxySignInRequestSurface.js +141 -0
  175. package/lib/module/ui/components/OxySignInRequestSurface.js.map +1 -0
  176. package/lib/module/ui/components/ProfileButton.js +1 -1
  177. package/lib/module/ui/components/ProfileButton.js.map +1 -1
  178. package/lib/module/ui/components/SettingsIcon.js +1 -1
  179. package/lib/module/ui/components/SettingsIcon.js.map +1 -1
  180. package/lib/module/ui/components/authChooser/AccountsMenuView.js +523 -0
  181. package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -0
  182. package/lib/module/ui/components/authChooser/SignInEntryView.js +85 -0
  183. package/lib/module/ui/components/authChooser/SignInEntryView.js.map +1 -0
  184. package/lib/module/ui/components/authChooser/SignInRequestView.js +101 -0
  185. package/lib/module/ui/components/authChooser/SignInRequestView.js.map +1 -0
  186. package/lib/module/ui/components/authChooser/SignUpView.js +184 -0
  187. package/lib/module/ui/components/authChooser/SignUpView.js.map +1 -0
  188. package/lib/module/ui/components/authChooser/TroubleDisclosure.js +57 -0
  189. package/lib/module/ui/components/authChooser/TroubleDisclosure.js.map +1 -0
  190. package/lib/module/ui/components/authChooser/primitives.js +163 -0
  191. package/lib/module/ui/components/authChooser/primitives.js.map +1 -0
  192. package/lib/module/ui/components/authChooser/requestSurfaces.js +143 -0
  193. package/lib/module/ui/components/authChooser/requestSurfaces.js.map +1 -0
  194. package/lib/module/ui/components/authChooser/signInProgress.js +50 -0
  195. package/lib/module/ui/components/authChooser/signInProgress.js.map +1 -0
  196. package/lib/module/ui/components/{oxyAuthChooserStyles.js → authChooser/styles.js} +19 -1
  197. package/lib/module/ui/components/authChooser/styles.js.map +1 -0
  198. package/lib/module/ui/components/authChooser/types.js +66 -0
  199. package/lib/module/ui/components/authChooser/types.js.map +1 -0
  200. package/lib/module/ui/components/authChooser/useUsernameAvailability.js +46 -0
  201. package/lib/module/ui/components/authChooser/useUsernameAvailability.js.map +1 -0
  202. package/lib/module/ui/components/fileManagement/AnimatedButton.js +1 -1
  203. package/lib/module/ui/components/fileManagement/AnimatedButton.js.map +1 -1
  204. package/lib/module/ui/components/fileManagement/FileDetailsModal.js +1 -1
  205. package/lib/module/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
  206. package/lib/module/ui/components/fileManagement/FileViewer.js +1 -1
  207. package/lib/module/ui/components/fileManagement/FileViewer.js.map +1 -1
  208. package/lib/module/ui/components/fileManagement/UploadPreview.js +1 -1
  209. package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
  210. package/lib/module/ui/components/modals/DeleteAccountModal.js +1 -1
  211. package/lib/module/ui/components/modals/DeleteAccountModal.js.map +1 -1
  212. package/lib/module/ui/components/payment/PaymentDetailsStep.js +1 -1
  213. package/lib/module/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  214. package/lib/module/ui/components/payment/PaymentMethodStep.js +1 -1
  215. package/lib/module/ui/components/payment/PaymentMethodStep.js.map +1 -1
  216. package/lib/module/ui/components/payment/PaymentReviewStep.js +1 -1
  217. package/lib/module/ui/components/payment/PaymentReviewStep.js.map +1 -1
  218. package/lib/module/ui/components/payment/PaymentSuccessStep.js +1 -1
  219. package/lib/module/ui/components/payment/PaymentSuccessStep.js.map +1 -1
  220. package/lib/module/ui/components/payment/PaymentSummaryStep.js +1 -1
  221. package/lib/module/ui/components/payment/PaymentSummaryStep.js.map +1 -1
  222. package/lib/module/ui/context/OxyContext.js +203 -32
  223. package/lib/module/ui/context/OxyContext.js.map +1 -1
  224. package/lib/module/ui/context/commitSessionFlow.js +42 -0
  225. package/lib/module/ui/context/commitSessionFlow.js.map +1 -1
  226. package/lib/module/ui/context/useOxyAccountGraph.js +13 -5
  227. package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
  228. package/lib/module/ui/hooks/useSwitchableAccounts.js +6 -1
  229. package/lib/module/ui/hooks/useSwitchableAccounts.js.map +1 -1
  230. package/lib/module/ui/index.js +0 -1
  231. package/lib/module/ui/index.js.map +1 -1
  232. package/lib/module/ui/oauth/browserAuthTransport.js +165 -0
  233. package/lib/module/ui/oauth/browserAuthTransport.js.map +1 -0
  234. package/lib/module/ui/oauth/completeOAuthCode.js +75 -0
  235. package/lib/module/ui/oauth/completeOAuthCode.js.map +1 -0
  236. package/lib/module/ui/oauth/legacyRedirectLanes.js +44 -0
  237. package/lib/module/ui/oauth/legacyRedirectLanes.js.map +1 -0
  238. package/lib/module/ui/oauth/oauthHandshake.js +50 -0
  239. package/lib/module/ui/oauth/oauthHandshake.js.map +1 -0
  240. package/lib/module/ui/oauth/oauthPopup.js +221 -0
  241. package/lib/module/ui/oauth/oauthPopup.js.map +1 -0
  242. package/lib/module/ui/oauth/oauthPopupMessages.js +135 -0
  243. package/lib/module/ui/oauth/oauthPopupMessages.js.map +1 -0
  244. package/lib/module/ui/oauth/types.js +2 -0
  245. package/lib/module/ui/oauth/types.js.map +1 -0
  246. package/lib/module/ui/screens/AccountMembersScreen.js +1 -1
  247. package/lib/module/ui/screens/AccountMembersScreen.js.map +1 -1
  248. package/lib/module/ui/screens/CreateAccountScreen.js +1 -1
  249. package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
  250. package/lib/module/ui/screens/EditProfileFieldScreen.js +1 -1
  251. package/lib/module/ui/screens/EditProfileFieldScreen.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 +1 -1
  255. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  256. package/lib/module/ui/screens/FileManagementScreen.js +2 -1
  257. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  258. package/lib/module/ui/screens/LanguageSelectorScreen.js +1 -1
  259. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  260. package/lib/module/ui/screens/ManageAccountScreen.js +1 -1
  261. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  262. package/lib/module/ui/screens/PaymentGatewayScreen.js +1 -1
  263. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  264. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1 -1
  265. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  266. package/lib/module/ui/screens/ProfileScreen.js +1 -1
  267. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  268. package/lib/module/ui/screens/UserListScreen.js +1 -1
  269. package/lib/module/ui/screens/UserListScreen.js.map +1 -1
  270. package/lib/module/ui/screens/WelcomeNewUserScreen.js +1 -1
  271. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  272. package/lib/module/ui/screens/fileManagement/FileLibraryError.js +1 -1
  273. package/lib/module/ui/screens/fileManagement/FileLibraryError.js.map +1 -1
  274. package/lib/module/ui/screens/fileManagement/FileListSection.js +1 -1
  275. package/lib/module/ui/screens/fileManagement/FileListSection.js.map +1 -1
  276. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +2 -1
  277. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  278. package/lib/module/ui/screens/fileManagement/UploadBar.js +1 -1
  279. package/lib/module/ui/screens/fileManagement/UploadBar.js.map +1 -1
  280. package/lib/module/ui/screens/trust/TrustCenterScreen.js +1 -1
  281. package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  282. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +1 -1
  283. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  284. package/lib/module/ui/screens/trust/TrustRewardsScreen.js +1 -1
  285. package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  286. package/lib/module/ui/server.js +0 -2
  287. package/lib/module/ui/server.js.map +1 -1
  288. package/lib/module/ui/session/authStore.js +5 -75
  289. package/lib/module/ui/session/authStore.js.map +1 -1
  290. package/lib/module/ui/session/createSessionClient.js +11 -3
  291. package/lib/module/ui/session/createSessionClient.js.map +1 -1
  292. package/lib/module/ui/session/identityBinding.js +89 -0
  293. package/lib/module/ui/session/identityBinding.js.map +1 -0
  294. package/lib/module/ui/session/index.js +5 -2
  295. package/lib/module/ui/session/index.js.map +1 -1
  296. package/lib/module/ui/session/nativeSecureStorage.js +88 -0
  297. package/lib/module/ui/session/nativeSecureStorage.js.map +1 -0
  298. package/lib/module/ui/session/tokenTransport.js +11 -1
  299. package/lib/module/ui/session/tokenTransport.js.map +1 -1
  300. package/lib/module/ui/utils/crossOriginRestore.js +4 -3
  301. package/lib/module/ui/utils/crossOriginRestore.js.map +1 -1
  302. package/lib/module/ui/utils/deliveryPlatform.js +55 -0
  303. package/lib/module/ui/utils/deliveryPlatform.js.map +1 -0
  304. package/lib/module/ui/utils/oauthReturn.js +70 -46
  305. package/lib/module/ui/utils/oauthReturn.js.map +1 -1
  306. package/lib/typescript/commonjs/index.d.ts +9 -1
  307. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  308. package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts +141 -0
  309. package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts.map +1 -0
  310. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts +34 -2
  311. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  312. package/lib/typescript/commonjs/ui/client.d.ts +0 -1
  313. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  314. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  315. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts +16 -29
  316. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  317. package/lib/typescript/commonjs/ui/components/OxyConsentScreen.d.ts.map +1 -1
  318. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  319. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts +17 -12
  320. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts.map +1 -1
  321. package/lib/typescript/commonjs/ui/components/OxySignInRequestSurface.d.ts +108 -0
  322. package/lib/typescript/commonjs/ui/components/OxySignInRequestSurface.d.ts.map +1 -0
  323. package/lib/typescript/commonjs/ui/components/SettingsIcon.d.ts +1 -1
  324. package/lib/typescript/commonjs/ui/components/SettingsIcon.d.ts.map +1 -1
  325. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts +38 -0
  326. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -0
  327. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +32 -0
  328. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +1 -0
  329. package/lib/typescript/commonjs/ui/components/authChooser/SignInRequestView.d.ts +34 -0
  330. package/lib/typescript/commonjs/ui/components/authChooser/SignInRequestView.d.ts.map +1 -0
  331. package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts +34 -0
  332. package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts.map +1 -0
  333. package/lib/typescript/commonjs/ui/components/authChooser/TroubleDisclosure.d.ts +36 -0
  334. package/lib/typescript/commonjs/ui/components/authChooser/TroubleDisclosure.d.ts.map +1 -0
  335. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +55 -0
  336. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -0
  337. package/lib/typescript/commonjs/ui/components/authChooser/requestSurfaces.d.ts +58 -0
  338. package/lib/typescript/commonjs/ui/components/authChooser/requestSurfaces.d.ts.map +1 -0
  339. package/lib/typescript/commonjs/ui/components/authChooser/signInProgress.d.ts +26 -0
  340. package/lib/typescript/commonjs/ui/components/authChooser/signInProgress.d.ts.map +1 -0
  341. package/lib/typescript/{module/ui/components/oxyAuthChooserStyles.d.ts → commonjs/ui/components/authChooser/styles.d.ts} +19 -1
  342. package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts.map +1 -0
  343. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +103 -0
  344. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -0
  345. package/lib/typescript/commonjs/ui/components/authChooser/useUsernameAvailability.d.ts +16 -0
  346. package/lib/typescript/commonjs/ui/components/authChooser/useUsernameAvailability.d.ts.map +1 -0
  347. package/lib/typescript/commonjs/ui/components/payment/types.d.ts +1 -1
  348. package/lib/typescript/commonjs/ui/components/payment/types.d.ts.map +1 -1
  349. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  350. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts +40 -0
  351. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts.map +1 -1
  352. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +44 -1
  353. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  354. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +7 -1
  355. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  356. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
  357. package/lib/typescript/commonjs/ui/index.d.ts +0 -1
  358. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  359. package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts +56 -0
  360. package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts.map +1 -0
  361. package/lib/typescript/commonjs/ui/oauth/completeOAuthCode.d.ts +49 -0
  362. package/lib/typescript/commonjs/ui/oauth/completeOAuthCode.d.ts.map +1 -0
  363. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts +40 -0
  364. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts.map +1 -0
  365. package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts +50 -0
  366. package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts.map +1 -0
  367. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts +77 -0
  368. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts.map +1 -0
  369. package/lib/typescript/commonjs/ui/oauth/oauthPopupMessages.d.ts +67 -0
  370. package/lib/typescript/commonjs/ui/oauth/oauthPopupMessages.d.ts.map +1 -0
  371. package/lib/typescript/commonjs/ui/oauth/types.d.ts +176 -0
  372. package/lib/typescript/commonjs/ui/oauth/types.d.ts.map +1 -0
  373. package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
  374. package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
  375. package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
  376. package/lib/typescript/commonjs/ui/server.d.ts +0 -2
  377. package/lib/typescript/commonjs/ui/server.d.ts.map +1 -1
  378. package/lib/typescript/commonjs/ui/session/authStore.d.ts +3 -7
  379. package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
  380. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts +8 -1
  381. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts.map +1 -1
  382. package/lib/typescript/commonjs/ui/session/identityBinding.d.ts +66 -0
  383. package/lib/typescript/commonjs/ui/session/identityBinding.d.ts.map +1 -0
  384. package/lib/typescript/commonjs/ui/session/index.d.ts +6 -2
  385. package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
  386. package/lib/typescript/commonjs/ui/session/nativeSecureStorage.d.ts +25 -0
  387. package/lib/typescript/commonjs/ui/session/nativeSecureStorage.d.ts.map +1 -0
  388. package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts +8 -1
  389. package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts.map +1 -1
  390. package/lib/typescript/commonjs/ui/types/navigation.d.ts +44 -0
  391. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  392. package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts.map +1 -1
  393. package/lib/typescript/commonjs/ui/utils/deliveryPlatform.d.ts +33 -0
  394. package/lib/typescript/commonjs/ui/utils/deliveryPlatform.d.ts.map +1 -0
  395. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +1 -1
  396. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
  397. package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts +30 -16
  398. package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts.map +1 -1
  399. package/lib/typescript/module/index.d.ts +9 -1
  400. package/lib/typescript/module/index.d.ts.map +1 -1
  401. package/lib/typescript/module/notifications/deviceNotifications.d.ts +141 -0
  402. package/lib/typescript/module/notifications/deviceNotifications.d.ts.map +1 -0
  403. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts +34 -2
  404. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  405. package/lib/typescript/module/ui/client.d.ts +0 -1
  406. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  407. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  408. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts +16 -29
  409. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  410. package/lib/typescript/module/ui/components/OxyConsentScreen.d.ts.map +1 -1
  411. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  412. package/lib/typescript/module/ui/components/OxySignInButton.d.ts +17 -12
  413. package/lib/typescript/module/ui/components/OxySignInButton.d.ts.map +1 -1
  414. package/lib/typescript/module/ui/components/OxySignInRequestSurface.d.ts +108 -0
  415. package/lib/typescript/module/ui/components/OxySignInRequestSurface.d.ts.map +1 -0
  416. package/lib/typescript/module/ui/components/SettingsIcon.d.ts +1 -1
  417. package/lib/typescript/module/ui/components/SettingsIcon.d.ts.map +1 -1
  418. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts +38 -0
  419. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -0
  420. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +32 -0
  421. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +1 -0
  422. package/lib/typescript/module/ui/components/authChooser/SignInRequestView.d.ts +34 -0
  423. package/lib/typescript/module/ui/components/authChooser/SignInRequestView.d.ts.map +1 -0
  424. package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts +34 -0
  425. package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts.map +1 -0
  426. package/lib/typescript/module/ui/components/authChooser/TroubleDisclosure.d.ts +36 -0
  427. package/lib/typescript/module/ui/components/authChooser/TroubleDisclosure.d.ts.map +1 -0
  428. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +55 -0
  429. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -0
  430. package/lib/typescript/module/ui/components/authChooser/requestSurfaces.d.ts +58 -0
  431. package/lib/typescript/module/ui/components/authChooser/requestSurfaces.d.ts.map +1 -0
  432. package/lib/typescript/module/ui/components/authChooser/signInProgress.d.ts +26 -0
  433. package/lib/typescript/module/ui/components/authChooser/signInProgress.d.ts.map +1 -0
  434. package/lib/typescript/{commonjs/ui/components/oxyAuthChooserStyles.d.ts → module/ui/components/authChooser/styles.d.ts} +19 -1
  435. package/lib/typescript/module/ui/components/authChooser/styles.d.ts.map +1 -0
  436. package/lib/typescript/module/ui/components/authChooser/types.d.ts +103 -0
  437. package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -0
  438. package/lib/typescript/module/ui/components/authChooser/useUsernameAvailability.d.ts +16 -0
  439. package/lib/typescript/module/ui/components/authChooser/useUsernameAvailability.d.ts.map +1 -0
  440. package/lib/typescript/module/ui/components/payment/types.d.ts +1 -1
  441. package/lib/typescript/module/ui/components/payment/types.d.ts.map +1 -1
  442. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  443. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts +40 -0
  444. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts.map +1 -1
  445. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +44 -1
  446. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  447. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +7 -1
  448. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  449. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
  450. package/lib/typescript/module/ui/index.d.ts +0 -1
  451. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  452. package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts +56 -0
  453. package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts.map +1 -0
  454. package/lib/typescript/module/ui/oauth/completeOAuthCode.d.ts +49 -0
  455. package/lib/typescript/module/ui/oauth/completeOAuthCode.d.ts.map +1 -0
  456. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts +40 -0
  457. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts.map +1 -0
  458. package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts +50 -0
  459. package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts.map +1 -0
  460. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts +77 -0
  461. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts.map +1 -0
  462. package/lib/typescript/module/ui/oauth/oauthPopupMessages.d.ts +67 -0
  463. package/lib/typescript/module/ui/oauth/oauthPopupMessages.d.ts.map +1 -0
  464. package/lib/typescript/module/ui/oauth/types.d.ts +176 -0
  465. package/lib/typescript/module/ui/oauth/types.d.ts.map +1 -0
  466. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
  467. package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
  468. package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
  469. package/lib/typescript/module/ui/server.d.ts +0 -2
  470. package/lib/typescript/module/ui/server.d.ts.map +1 -1
  471. package/lib/typescript/module/ui/session/authStore.d.ts +3 -7
  472. package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
  473. package/lib/typescript/module/ui/session/createSessionClient.d.ts +8 -1
  474. package/lib/typescript/module/ui/session/createSessionClient.d.ts.map +1 -1
  475. package/lib/typescript/module/ui/session/identityBinding.d.ts +66 -0
  476. package/lib/typescript/module/ui/session/identityBinding.d.ts.map +1 -0
  477. package/lib/typescript/module/ui/session/index.d.ts +6 -2
  478. package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
  479. package/lib/typescript/module/ui/session/nativeSecureStorage.d.ts +25 -0
  480. package/lib/typescript/module/ui/session/nativeSecureStorage.d.ts.map +1 -0
  481. package/lib/typescript/module/ui/session/tokenTransport.d.ts +8 -1
  482. package/lib/typescript/module/ui/session/tokenTransport.d.ts.map +1 -1
  483. package/lib/typescript/module/ui/types/navigation.d.ts +44 -0
  484. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  485. package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts.map +1 -1
  486. package/lib/typescript/module/ui/utils/deliveryPlatform.d.ts +33 -0
  487. package/lib/typescript/module/ui/utils/deliveryPlatform.d.ts.map +1 -0
  488. package/lib/typescript/module/ui/utils/fileManagement.d.ts +1 -1
  489. package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
  490. package/lib/typescript/module/ui/utils/oauthReturn.d.ts +30 -16
  491. package/lib/typescript/module/ui/utils/oauthReturn.d.ts.map +1 -1
  492. package/package.json +15 -7
  493. package/src/index.ts +50 -5
  494. package/src/notifications/deviceNotifications.ts +395 -0
  495. package/src/ui/boot/__tests__/coldBootWebAuthMode.test.ts +281 -0
  496. package/src/ui/boot/runProviderColdBoot.ts +83 -13
  497. package/src/ui/client.ts +0 -1
  498. package/src/ui/components/AvatarCameraBadge.tsx +1 -1
  499. package/src/ui/components/OxyAccountDialogScreen.tsx +20 -3
  500. package/src/ui/components/OxyAuthChooser.tsx +91 -1230
  501. package/src/ui/components/OxyConsentScreen.tsx +56 -13
  502. package/src/ui/components/OxyProvider.tsx +4 -4
  503. package/src/ui/components/OxySignInButton.tsx +119 -78
  504. package/src/ui/components/OxySignInRequestSurface.tsx +202 -0
  505. package/src/ui/components/ProfileButton.tsx +1 -1
  506. package/src/ui/components/SettingsIcon.tsx +1 -1
  507. package/src/ui/components/__tests__/OxyConsentScreen.test.tsx +27 -0
  508. package/src/ui/components/authChooser/AccountsMenuView.tsx +569 -0
  509. package/src/ui/components/authChooser/SignInEntryView.tsx +121 -0
  510. package/src/ui/components/authChooser/SignInRequestView.tsx +130 -0
  511. package/src/ui/components/authChooser/SignUpView.tsx +174 -0
  512. package/src/ui/components/authChooser/TroubleDisclosure.tsx +73 -0
  513. package/src/ui/components/authChooser/primitives.tsx +144 -0
  514. package/src/ui/components/authChooser/requestSurfaces.tsx +120 -0
  515. package/src/ui/components/authChooser/signInProgress.ts +54 -0
  516. package/src/ui/components/{oxyAuthChooserStyles.ts → authChooser/styles.ts} +18 -0
  517. package/src/ui/components/authChooser/types.ts +120 -0
  518. package/src/ui/components/authChooser/useUsernameAvailability.ts +60 -0
  519. package/src/ui/components/fileManagement/AnimatedButton.tsx +1 -1
  520. package/src/ui/components/fileManagement/FileDetailsModal.tsx +1 -1
  521. package/src/ui/components/fileManagement/FileViewer.tsx +1 -1
  522. package/src/ui/components/fileManagement/UploadPreview.tsx +1 -1
  523. package/src/ui/components/modals/DeleteAccountModal.tsx +1 -1
  524. package/src/ui/components/payment/PaymentDetailsStep.tsx +1 -1
  525. package/src/ui/components/payment/PaymentMethodStep.tsx +1 -1
  526. package/src/ui/components/payment/PaymentReviewStep.tsx +1 -1
  527. package/src/ui/components/payment/PaymentSuccessStep.tsx +1 -1
  528. package/src/ui/components/payment/PaymentSummaryStep.tsx +1 -1
  529. package/src/ui/components/payment/types.ts +1 -1
  530. package/src/ui/context/OxyContext.tsx +220 -24
  531. package/src/ui/context/__tests__/commitSessionFlow.test.ts +89 -0
  532. package/src/ui/context/commitSessionFlow.ts +61 -0
  533. package/src/ui/context/oxyContextTypes.ts +45 -1
  534. package/src/ui/context/useOxyAccountGraph.ts +19 -5
  535. package/src/ui/hooks/useSwitchableAccounts.ts +12 -1
  536. package/src/ui/index.ts +0 -1
  537. package/src/ui/oauth/__tests__/browserAuthTransport.test.ts +335 -0
  538. package/src/ui/oauth/__tests__/completeOAuthCode.test.ts +142 -0
  539. package/src/ui/oauth/__tests__/oauthPopup.test.ts +326 -0
  540. package/src/ui/oauth/__tests__/oauthPopupMessages.test.ts +189 -0
  541. package/src/ui/oauth/__tests__/sharedCompletionPath.test.ts +174 -0
  542. package/src/ui/oauth/browserAuthTransport.ts +187 -0
  543. package/src/ui/oauth/completeOAuthCode.ts +93 -0
  544. package/src/ui/oauth/legacyRedirectLanes.ts +43 -0
  545. package/src/ui/oauth/oauthHandshake.ts +74 -0
  546. package/src/ui/oauth/oauthPopup.ts +219 -0
  547. package/src/ui/oauth/oauthPopupMessages.ts +136 -0
  548. package/src/ui/oauth/types.ts +150 -0
  549. package/src/ui/screens/AccountMembersScreen.tsx +1 -1
  550. package/src/ui/screens/CreateAccountScreen.tsx +1 -1
  551. package/src/ui/screens/EditProfileFieldScreen.tsx +1 -1
  552. package/src/ui/screens/FAQScreen.tsx +1 -1
  553. package/src/ui/screens/FeedbackScreen.tsx +2 -1
  554. package/src/ui/screens/FileManagementScreen.tsx +2 -1
  555. package/src/ui/screens/LanguageSelectorScreen.tsx +1 -1
  556. package/src/ui/screens/ManageAccountScreen.tsx +1 -1
  557. package/src/ui/screens/PaymentGatewayScreen.tsx +1 -1
  558. package/src/ui/screens/PremiumSubscriptionScreen.tsx +1 -1
  559. package/src/ui/screens/ProfileScreen.tsx +1 -1
  560. package/src/ui/screens/UserListScreen.tsx +1 -1
  561. package/src/ui/screens/WelcomeNewUserScreen.tsx +1 -1
  562. package/src/ui/screens/fileManagement/FileLibraryError.tsx +1 -1
  563. package/src/ui/screens/fileManagement/FileListSection.tsx +1 -1
  564. package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +2 -1
  565. package/src/ui/screens/fileManagement/UploadBar.tsx +1 -1
  566. package/src/ui/screens/trust/TrustCenterScreen.tsx +1 -1
  567. package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +1 -1
  568. package/src/ui/screens/trust/TrustRewardsScreen.tsx +1 -1
  569. package/src/ui/server.ts +0 -2
  570. package/src/ui/session/__tests__/createSessionClient.test.ts +26 -0
  571. package/src/ui/session/__tests__/tokenTransport.test.ts +34 -0
  572. package/src/ui/session/authStore.ts +5 -89
  573. package/src/ui/session/createSessionClient.ts +15 -2
  574. package/src/ui/session/identityBinding.ts +116 -0
  575. package/src/ui/session/index.ts +6 -2
  576. package/src/ui/session/nativeSecureStorage.ts +98 -0
  577. package/src/ui/session/tokenTransport.ts +14 -1
  578. package/src/ui/types/navigation.ts +44 -1
  579. package/src/ui/utils/crossOriginRestore.ts +4 -7
  580. package/src/ui/utils/deliveryPlatform.ts +65 -0
  581. package/src/ui/utils/fileManagement.ts +1 -1
  582. package/src/ui/utils/oauthReturn.ts +74 -65
  583. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  584. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  585. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  586. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  587. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  588. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  589. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  590. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  591. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  592. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  593. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  594. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  595. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  596. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  597. package/lib/commonjs/ui/components/FontLoader.js +0 -35
  598. package/lib/commonjs/ui/components/FontLoader.js.map +0 -1
  599. package/lib/commonjs/ui/components/FontLoader.native.js +0 -88
  600. package/lib/commonjs/ui/components/FontLoader.native.js.map +0 -1
  601. package/lib/commonjs/ui/components/oxyAuthChooserStyles.js.map +0 -1
  602. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  603. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  604. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  605. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  606. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  607. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  608. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  609. package/lib/module/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  610. package/lib/module/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  611. package/lib/module/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  612. package/lib/module/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  613. package/lib/module/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  614. package/lib/module/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  615. package/lib/module/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  616. package/lib/module/ui/components/FontLoader.js +0 -29
  617. package/lib/module/ui/components/FontLoader.js.map +0 -1
  618. package/lib/module/ui/components/FontLoader.native.js +0 -83
  619. package/lib/module/ui/components/FontLoader.native.js.map +0 -1
  620. package/lib/module/ui/components/oxyAuthChooserStyles.js.map +0 -1
  621. package/lib/typescript/commonjs/ui/components/FontLoader.d.ts +0 -24
  622. package/lib/typescript/commonjs/ui/components/FontLoader.d.ts.map +0 -1
  623. package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts +0 -13
  624. package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts.map +0 -1
  625. package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts.map +0 -1
  626. package/lib/typescript/module/ui/components/FontLoader.d.ts +0 -24
  627. package/lib/typescript/module/ui/components/FontLoader.d.ts.map +0 -1
  628. package/lib/typescript/module/ui/components/FontLoader.native.d.ts +0 -13
  629. package/lib/typescript/module/ui/components/FontLoader.native.d.ts.map +0 -1
  630. package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts.map +0 -1
  631. package/src/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  632. package/src/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  633. package/src/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  634. package/src/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  635. package/src/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  636. package/src/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  637. package/src/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  638. package/src/ui/components/FontLoader.native.tsx +0 -88
  639. package/src/ui/components/FontLoader.tsx +0 -27
@@ -12,35 +12,22 @@
12
12
  * cross-origin passkey popup (b2) — same chooser, two hosts, two completion
13
13
  * strategies via the `onComplete` prop. Neither host duplicates view logic.
14
14
  *
15
- * Views (from `snapshot.view`):
16
- * - `accounts` the unified `SwitchableAccount[]` list. Tapping a row
17
- * switches through `controller.switchTo(accountId)`, the active row is
18
- * flagged, and a "+ Add account" row opens the sign-in entry.
19
- * - `add` / `signin` — the sign-in entry. On WEB this auto-starts "Sign in
20
- * with Oxy" (native shared-keychain silently, else the QR handoff) the
21
- * instant the view is entered the QR is the PRIMARY web surface, not a
22
- * button behind a click. On NATIVE it stays button-driven (unchanged):
23
- * primary "Sign in with Oxy", secondary "Scan a QR from another device".
24
- * Both platforms get a footer entry into `signup`.
25
- * - `signup` account creation. Commons is ALWAYS the priority path (owner
26
- * mandate) and leads everywhere it appears: native shows only "Create your
27
- * identity in Commons" (or "Get Commons" first, if not installed); web on
28
- * a first-party Oxy origin leads with the SAME "Get Commons" CTA, with
29
- * inline passkey creation (username + `registerWithPasskey`) offered
30
- * UNDERNEATH as the de-emphasized "don't want to install anything"
31
- * alternative — never co-equal, never a competing button. Anywhere else (a
32
- * non-Oxy web origin, before the b2 hub-relay ships) shows an honest "not
33
- * available here yet" message instead of a broken button.
34
- * - `qr` — the cross-device Commons handoff, and the PRIMARY web sign-in
35
- * surface. On a first-party Oxy origin this ALSO carries a "No Commons?"
36
- * passkey link — identity is ONE thing (Commons key or browser passkey,
37
- * same Oxy ID), so there is no separate "sign in with a passkey" button
38
- * anywhere in this file, but passkey is explicitly the LIGHTWEIGHT
39
- * ALTERNATIVE for someone who doesn't want to install Commons, never
40
- * co-equal: same small-text-link subordination, same framing, wherever it
41
- * appears. Native additionally branches on `commonsAvailability`: when
42
- * Commons isn't installed, this leads with a "Get Commons" CTA instead of
43
- * a same-device dead-end QR.
15
+ * This file owns WIRING only: the controller binding, the action handlers, and
16
+ * which view module renders. Every view lives in `./authChooser/`, one
17
+ * responsibility each:
18
+ *
19
+ * - `accounts` `AccountsMenuView` — the signed-in Oxy account menu.
20
+ * - `add` / `signin` `SignInEntryView` ONE primary action, "Continue with
21
+ * Oxy" (issue #691, Phase 5). On WEB this view is transient: the flow
22
+ * auto-starts the instant the view is reached, because the request surface
23
+ * (a QR on an unknown desktop, "Check Commons on your phone" where Oxy could
24
+ * deliver) IS the primary route there, never something behind a second tap.
25
+ * - `qr` `SignInRequestView` the ACTIVE REQUEST: the controller-bound
26
+ * wiring over the shared, presentational `OxySignInRequestSurface` (the same
27
+ * component the auth.oxy.so IdP mounts from its OAuth-bound request). It maps
28
+ * `snapshot.signIn` onto that surface's props; alternatives stay behind
29
+ * "Having trouble?" until the chosen route reports `routeFailed`.
30
+ * - `signup` `SignUpView` account creation, Commons-first.
44
31
  *
45
32
  * Per-account color re-theming uses Bloom's `APP_COLOR_PRESETS` + `BloomColorScope`
46
33
  * (same visual language auth.oxy.so uses). Base theming is `useTheme()` + a
@@ -48,21 +35,11 @@
48
35
  * that do not use NativeWind (e.g. the accounts app).
49
36
  */
50
37
 
51
- import { Fragment, useCallback, useMemo, useRef, useState, useSyncExternalStore } from 'react';
52
- import { Linking, Platform, Pressable, TextInput, View } from 'react-native';
53
- import Animated, { Extrapolation, interpolate, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
54
- import { MaterialCommunityIcons } from '@expo/vector-icons';
55
- import QRCode from 'react-native-qrcode-svg';
56
- import { Avatar } from '@oxyhq/bloom/avatar';
57
- import { AvatarGroup } from '@oxyhq/bloom/avatar-group';
58
- import { Button } from '@oxyhq/bloom/button';
59
- import { PressableScale } from '@oxyhq/bloom/pressable-scale';
60
- import { CompositionBar } from '@oxyhq/bloom/composition-bar';
61
- import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
38
+ import { useCallback, useMemo, useState, useSyncExternalStore } from 'react';
39
+ import { Linking, Platform } from 'react-native';
62
40
  import { toast } from '@oxyhq/bloom';
63
- import { Text } from '@oxyhq/bloom/typography';
64
- import { useTheme, BloomColorScope, APP_COLOR_NAMES, APP_COLOR_PRESETS } from '@oxyhq/bloom/theme';
65
- import { getNormalizedUserHandle, isOxyRpOrigin } from '@oxyhq/core';
41
+ import { useTheme } from '@oxyhq/bloom/theme';
42
+ import { isOxyRpOrigin } from '@oxyhq/core';
66
43
  import { useQueryClient } from '@tanstack/react-query';
67
44
  import { useOxy } from "../context/OxyContext.js";
68
45
  import { useI18n } from "../hooks/useI18n.js";
@@ -70,16 +47,11 @@ import { getAccountDialogConsumerHooks } from "../navigation/accountDialogManage
70
47
  import { isWebBrowser } from "../utils/isWebBrowser.js";
71
48
  import { getCommonsAcquisitionUrl } from "../utils/commonsStoreLinks.js";
72
49
  import { useAccountStorageUsage } from "../hooks/queries/useServicesQueries.js";
73
- import { authChooserStyles as styles } from "./oxyAuthChooserStyles.js";
74
- import AvatarCameraBadge from "./AvatarCameraBadge.js";
75
-
76
- /** Diameter of a row avatar (the sign-in view's account rows). */
77
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
78
- const ROW_AVATAR_SIZE = 40;
79
- /** High-contrast QR colors — intentionally fixed (NOT themed) for scan reliability. */
80
- const QR_PLATE_BG = '#FFFFFF';
81
- const QR_FOREGROUND = '#000000';
82
- const QR_SIZE = 196;
50
+ import AccountsMenuView from "./authChooser/AccountsMenuView.js";
51
+ import SignInEntryView from "./authChooser/SignInEntryView.js";
52
+ import SignInRequestView from "./authChooser/SignInRequestView.js";
53
+ import SignUpView from "./authChooser/SignUpView.js";
54
+ import { jsx as _jsx } from "react/jsx-runtime";
83
55
  /** Commons' own identity-creation deep link (mirrors the `approve`/`attest`/`card` intents). */
84
56
  const COMMONS_CREATE_IDENTITY_URL = 'oxycommons://create-identity';
85
57
  /**
@@ -89,22 +61,6 @@ const COMMONS_CREATE_IDENTITY_URL = 'oxycommons://create-identity';
89
61
  * hands off to Commons; nothing here invents new API endpoints.
90
62
  */
91
63
  const ACCOUNTS_APP_URL = 'https://accounts.oxy.so';
92
- /**
93
- * Resolve an account's stored color (a named Bloom preset, e.g. `'purple'`) to
94
- * a concrete brand hex for the row accent. Falls back to the theme primary when
95
- * the account has no color or the value is not a recognized preset, so the accent
96
- * renders in EVERY consumer regardless of NativeWind availability.
97
- */
98
- function resolveAccentHex(color, fallback) {
99
- const preset = toPreset(color);
100
- return preset ? APP_COLOR_PRESETS[preset].hex : fallback;
101
- }
102
-
103
- /** Narrow a stored color string to a known `AppColorName`, or `undefined`. */
104
- function toPreset(color) {
105
- if (!color) return undefined;
106
- return APP_COLOR_NAMES.includes(color) ? color : undefined;
107
- }
108
64
  /**
109
65
  * The account switcher + sign-in/sign-up chooser. Mounted by `OxyAccountDialogScreen`
110
66
  * (wrapped in Bloom's `<Dialog>`) today; mountable bare by any future host that
@@ -142,7 +98,6 @@ const OxyAuthChooser = ({
142
98
  if (!isWebBrowser()) return 'none';
143
99
  return isOxyRpOrigin() ? 'direct' : 'hub';
144
100
  }, []);
145
- const passkeyAvailable = passkeyMode !== 'none';
146
101
  const [signInPasskeyPending, setSignInPasskeyPending] = useState(false);
147
102
  const handleSignInWithPasskey = useCallback(async () => {
148
103
  if (signInPasskeyPending) return;
@@ -154,7 +109,7 @@ const OxyAuthChooser = ({
154
109
  // A cancelled/failed ceremony keeps the view open so the user can retry
155
110
  // or fall back to the QR — surface the reason as a toast (owner mandate:
156
111
  // errors never render inline inside the dialog), never swallow.
157
- toast.error(error instanceof Error && error.message ? error.message : t('accountSwitcher.toasts.passkeySignInFailed') || 'Passkey sign-in failed.');
112
+ toast.error(error instanceof Error && error.message ? error.message : t('accountSwitcher.toasts.passkeySignInFailed'));
158
113
  } finally {
159
114
  setSignInPasskeyPending(false);
160
115
  }
@@ -169,20 +124,21 @@ const OxyAuthChooser = ({
169
124
  });
170
125
  onComplete?.();
171
126
  } catch (error) {
172
- toast.error(error instanceof Error && error.message ? error.message : t('signup.toasts.passkeyCreateFailed') || 'Account creation failed.');
127
+ toast.error(error instanceof Error && error.message ? error.message : t('signup.toasts.passkeyCreateFailed'));
173
128
  } finally {
174
129
  setCreatePasskeyPending(false);
175
130
  }
176
131
  }, [createPasskeyPending, registerWithPasskey, onComplete, t]);
177
132
 
178
133
  // Web: auto-start "Sign in with Oxy" when the sign-in entry becomes the shown
179
- // view — the QR handoff is the PRIMARY web surface, not a button behind a tap.
134
+ // view — the request surface is the PRIMARY web route, not something behind a
135
+ // second tap (the user's ONE action was the sign-in button that opened this).
180
136
  // `signInWithOxy()` tries the shared keychain first (silently, native-only)
181
- // then falls to the QR handoff, which is what actually renders. Driven from the
182
- // EVENTS that reach that view — the initial `subscribe` pass below (an
137
+ // then falls to the device flow, whose route the controller picks. Driven from
138
+ // the EVENTS that reach that view — the initial `subscribe` pass below (an
183
139
  // open-to-sign-in) and the add / back-to-sign-in handlers — never a watcher
184
- // effect. Guarded so it never restarts a live flow (phase must be idle) and is a
185
- // no-op on native (button-driven). Reads the live snapshot at call time (an
140
+ // effect. Guarded so it never restarts a live flow (phase must be idle) and is
141
+ // a no-op on native (button-driven). Reads the live snapshot at call time (an
186
142
  // event callback, not render), so it is stable across renders.
187
143
  const autoStartSignIn = useCallback(() => {
188
144
  if (!controller || !isWebBrowser()) return;
@@ -203,8 +159,8 @@ const OxyAuthChooser = ({
203
159
  // callbacks, not render/effect — so neither is a React effect hook:
204
160
  // 1. Sign-in device-flow failures (poll / socket / popup-cancel land on
205
161
  // `signIn` asynchronously) are toasted at the notification site, deduped
206
- // per subscription — NEVER an inline banner in the QR view (owner mandate,
207
- // same contract as account-switch).
162
+ // per subscription — NEVER an inline banner in the request view (owner
163
+ // mandate, same contract as account-switch).
208
164
  // 2. On subscribe (mount / re-subscribe — a passive effect, the SAME timing
209
165
  // the removed effects had) the web sign-in flow auto-starts if the opening
210
166
  // view is the sign-in entry.
@@ -252,7 +208,7 @@ const OxyAuthChooser = ({
252
208
  // re-fetches — the same side effects the context's own
253
209
  // `switchToAccount` performs.
254
210
  if (controller.getSnapshot().error) {
255
- toast.error(t('accountSwitcher.toasts.switchFailed') || 'There was a problem switching accounts. Please try again.');
211
+ toast.error(t('accountSwitcher.toasts.switchFailed'));
256
212
  return;
257
213
  }
258
214
  void refreshAccounts();
@@ -293,9 +249,31 @@ const OxyAuthChooser = ({
293
249
  onEditAvatar: () => openAvatarPicker()
294
250
  }), [handleSwitch, handleAdd, handleManage, openAvatarPicker]);
295
251
 
252
+ // Everything that is NOT the surface's one primary action. Wired once here;
253
+ // each view picks the subset that is a genuine alternative to ITS primary
254
+ // surface and hides them behind "Having trouble?" (issue #691).
255
+ const alternatives = useMemo(() => ({
256
+ passkeyAvailable: passkeyMode !== 'none',
257
+ // The hub-popup flow reports progress through `snapshot.signIn` (already
258
+ // rendered by the request view) — only the DIRECT ceremony uses this
259
+ // component-local pending flag. A ceremony FAILURE is toasted by
260
+ // `handleSignInWithPasskey`, never rendered inline.
261
+ passkeyPending: passkeyMode === 'direct' ? signInPasskeyPending : false,
262
+ onSignInWithPasskey: () => {
263
+ if (passkeyMode === 'direct') {
264
+ void handleSignInWithPasskey();
265
+ return;
266
+ }
267
+ void controller?.startPasskeyHubSignIn();
268
+ },
269
+ onShowQr: () => void controller?.showQr(),
270
+ onGetCommons: () => void Linking.openURL(getCommonsAcquisitionUrl(Platform.OS)),
271
+ onCreateAccount: () => controller?.startSignup()
272
+ }), [passkeyMode, signInPasskeyPending, handleSignInWithPasskey, controller]);
273
+
296
274
  // Real storage usage for the account menu's "Oxy storage" block. Disabled
297
275
  // (no fetch) until a private-API session exists, so it is inert on the
298
- // sign-in/QR/sign-up views; when present the block shows live used/total.
276
+ // sign-in/request/sign-up views; when present the block shows live used/total.
299
277
  const storageQuery = useAccountStorageUsage();
300
278
  const storage = useMemo(() => storageQuery.data ? {
301
279
  usedBytes: storageQuery.data.totalUsedBytes,
@@ -343,7 +321,7 @@ const OxyAuthChooser = ({
343
321
  return null;
344
322
  }
345
323
  if (view === 'accounts') {
346
- return /*#__PURE__*/_jsx(AccountsView, {
324
+ return /*#__PURE__*/_jsx(AccountsMenuView, {
347
325
  snapshot: snapshot,
348
326
  theme: theme,
349
327
  t: t,
@@ -353,20 +331,11 @@ const OxyAuthChooser = ({
353
331
  });
354
332
  }
355
333
  if (view === 'qr') {
356
- return /*#__PURE__*/_jsx(QrView, {
334
+ return /*#__PURE__*/_jsx(SignInRequestView, {
357
335
  snapshot: snapshot,
358
- theme: theme,
359
336
  t: t,
360
337
  onRetry: () => void controller.showQr(),
361
- passkeyAvailable: passkeyAvailable,
362
- onSignInWithPasskey: passkeyMode === 'direct' ? () => void handleSignInWithPasskey() : () => void controller.startPasskeyHubSignIn()
363
- // The hub-popup flow's pending state is `snapshot.signIn` (already
364
- // rendered elsewhere in this view) — only the DIRECT ceremony uses this
365
- // component-local pending flag. A ceremony FAILURE is surfaced as a
366
- // toast by `handleSignInWithPasskey`, never inline.
367
- ,
368
- passkeyPending: passkeyMode === 'direct' ? signInPasskeyPending : false,
369
- onCreateAccount: () => controller.startSignup()
338
+ alternatives: alternatives
370
339
  });
371
340
  }
372
341
  if (view === 'signup') {
@@ -376,1050 +345,24 @@ const OxyAuthChooser = ({
376
345
  t: t,
377
346
  oxyServices: oxyServices,
378
347
  passkeyMode: passkeyMode,
379
- onCreateWithPasskey: handleCreateWithPasskey,
348
+ onCreateWithPasskey: username => void handleCreateWithPasskey(username),
380
349
  createPending: createPasskeyPending,
381
350
  onOpenHub: () => void controller.startPasskeyHubSignIn(),
351
+ onCreateIdentityInCommons: () => void Linking.openURL(COMMONS_CREATE_IDENTITY_URL),
352
+ onGetCommons: alternatives.onGetCommons,
382
353
  onBackToSignIn: () => {
383
354
  controller.setView('signin');
384
355
  autoStartSignIn();
385
356
  }
386
357
  });
387
358
  }
388
- return /*#__PURE__*/_jsx(SignInView, {
359
+ return /*#__PURE__*/_jsx(SignInEntryView, {
389
360
  snapshot: snapshot,
390
361
  theme: theme,
391
362
  t: t,
392
363
  handlers: handlers,
393
- onSignInWithOxy: () => void controller.signInWithOxy(),
394
- onScanQr: () => void controller.showQr(),
395
- onCreateAccount: () => controller.startSignup()
396
- });
397
- };
398
-
399
- // ---------------------------------------------------------------------------
400
- // Accounts view — the signed-in Oxy account MENU (NativeWind)
401
- // ---------------------------------------------------------------------------
402
-
403
- /** Used/total storage bytes for the "Oxy storage" block, or `null` when unknown. */
404
-
405
- /** The account-menu row actions the container wires (deep-links / sheets / sign-out). */
406
-
407
- /**
408
- * Leading glyph for the rows that live in a Bloom grouped section (the MENU
409
- * block) and for the storage card's cloud, which lines its title up with them.
410
- * It is Bloom's OWN icon-slot size: `SettingsListItem` reserves a fixed 20px
411
- * leading column and Bloom is consumed exactly as it ships, so a menu glyph
412
- * larger than this would overhang into the row's title.
413
- */
414
- const ROW_ICON_SIZE = 20;
415
- /**
416
- * The switch card's two corner states. Collapsed it is one row and reads as a
417
- * PILL; opened it is a card holding rows, on the same 16px corner the Bloom
418
- * grouped section below it uses. Interpolated across the reveal, never snapped.
419
- */
420
- const SWITCH_CARD_PILL_RADIUS = 999;
421
- const SWITCH_CARD_RADIUS = 16;
422
- /**
423
- * The fraction of the reveal over which the corner resolves. The corner is a
424
- * FASTER gesture than the reveal — it has to be finished before the rows read as
425
- * rows, or the card still looks like a pill while a list falls out of it — so it
426
- * is clamped to the reveal's opening fraction instead of tracking it end to end.
427
- * Measured in a browser against the 240ms reveal: the corner reaches its card
428
- * value ~120ms in, with the list only ~20% revealed, and (mirrored) the pill is
429
- * back ~250ms into the close, with the list already down to ~0.
430
- */
431
- const SWITCH_CARD_RADIUS_SETTLE = 0.2;
432
- /** Diameter of an account row's avatar in the switch list (own markup). */
433
- const SWITCH_AVATAR_SIZE = 36;
434
- /** Glyph inside a bordered affordance badge, sized to the avatar it stands in for. */
435
- const BADGE_GLYPH_SIZE = 19;
436
- /** The hero block's large current-account avatar. */
437
- const HERO_AVATAR_SIZE = 72;
438
-
439
- /**
440
- * The hero's address line, shown under the "Hi, <name>!" greeting: the account's
441
- * canonical `@oxy.so` email when it has one, else its normalized `@handle`. Never
442
- * synthesizes a `username@oxy.so` address (the identity contract forbids it) — a
443
- * non-Oxy or missing email falls back to `getNormalizedUserHandle`.
444
- */
445
- function heroAddressLine(account) {
446
- if (account.email?.toLowerCase().endsWith('@oxy.so')) {
447
- return account.email;
448
- }
449
- const handle = getNormalizedUserHandle(account.user);
450
- return handle ? `@${handle}` : null;
451
- }
452
- /** Avatars shown in the switch row's facepile before it collapses into `+N`. */
453
- const FACEPILE_MAX = 2;
454
- /** Facepile avatar diameter — one clear step down from a switch-list avatar. */
455
- const FACEPILE_AVATAR_SIZE = 32;
456
- /**
457
- * Facepile overlap. Well under Bloom's `size / 3` default: the stack draws the
458
- * FIRST item on top, so a deep overlap would bury the trailing `+N` chip's own
459
- * label under the avatar before it.
460
- */
461
- const FACEPILE_OVERLAP = 4;
462
-
463
- /**
464
- * `bytes` → `"11.6 GB"`. Whole plan sizes read as whole numbers (`"17 GB"`, not
465
- * `"17.0 GB"`), and anything ≥ 100 GB drops the decimal entirely.
466
- */
467
- function formatStorageGb(bytes) {
468
- const gb = bytes / 1024 ** 3;
469
- if (gb >= 100 || Number.isInteger(gb)) return `${Math.round(gb)} GB`;
470
- return `${gb.toFixed(1)} GB`;
471
- }
472
- /**
473
- * A `Pressable` that appends a hover-tint NativeWind token while pointer-hovered.
474
- * The Metro web pipeline here does NOT emit NativeWind `hover:` variants, so hover
475
- * is driven by RN's cross-platform `onHoverIn`/`onHoverOut` (they fire only on web
476
- * via react-native-web; a no-op on native) toggling a plain background token —
477
- * the tint stays a NativeWind class, only the trigger is JS.
478
- */
479
- const HoverPressable = ({
480
- baseClassName,
481
- hoverClassName,
482
- ...rest
483
- }) => {
484
- const [hovered, setHovered] = useState(false);
485
- return /*#__PURE__*/_jsx(Pressable, {
486
- ...rest,
487
- className: hovered ? `${baseClassName} ${hoverClassName}` : baseClassName,
488
- onHoverIn: () => setHovered(true),
489
- onHoverOut: () => setHovered(false)
490
- });
491
- };
492
-
493
- /**
494
- * The signed-in Oxy account MENU — a Google-account-menu-style full menu built
495
- * entirely with NativeWind `className` (the dynamic per-account accent hex is
496
- * the one inline style NativeWind can't express). Structure mirrors the
497
- * approved demo:
498
- * - ACCOUNT on its own distinct panel surface: a COMPACT current-account row
499
- * (avatar + name + email + expand chevron) that toggles the switch list, a
500
- * "Manage your Oxy account" pill, and — when expanded — the other switchable
501
- * accounts + "Add another account" + "Manage accounts on this device".
502
- * - OXY STORAGE: cloud + used/total + a progress bar + Upgrade / Manage chips.
503
- * - MENU rows: Your data in Oxy · Oxy settings · Help & feedback · Sign out —
504
- * Bloom's grouped section (`SettingsListGroup`/`SettingsListItem`), the same
505
- * component every other SDK settings surface uses, not a local row copy.
506
- * - FOOTER: Privacy Policy · Terms of Service.
507
- *
508
- * All three blocks share ONE rhythm taken from that grouped section: a 12px
509
- * content inset, a 12px gap after the leading element, 16px between blocks, and
510
- * a 16px trailing chevron column.
511
- *
512
- * Collapse state is a plain `useState` toggled in the current row's press
513
- * handler — no effect hook, no derived-from-props sync. With only ONE account
514
- * (nothing to switch to) the chevron is hidden and the list renders inline so
515
- * "Add another account" stays reachable without a pointless toggle.
516
- */
517
- const AccountsView = ({
518
- snapshot,
519
- theme,
520
- t,
521
- handlers,
522
- storage,
523
- menu
524
- }) => {
525
- const [expanded, setExpanded] = useState(false);
526
- // Measured natural height of the switch list, so the reveal animates to an
527
- // exact height (and the content below reflows down smoothly) instead of a
528
- // guessed max. The measuring wrapper is style-based, NOT className'd — on
529
- // RN-Web `onLayout` never fires for className'd Views (see AGENTS.md).
530
- const [listContentHeight, setListContentHeight] = useState(0);
531
- // 0 = collapsed, 1 = expanded. Set imperatively in the toggle handler (no
532
- // effect hook). On RN-Web there is no worklets plugin, so every shared value a
533
- // mapper reads MUST be in its deps array or it freezes on the first frame
534
- // (AGENTS.md "Reanimated (web)").
535
- const listProgress = useSharedValue(0);
536
- const listStyle = useAnimatedStyle(() => ({
537
- height: listProgress.value * listContentHeight,
538
- opacity: listProgress.value
539
- }), [listProgress, listContentHeight]);
540
- const chevronStyle = useAnimatedStyle(() => ({
541
- transform: [{
542
- rotate: `${listProgress.value * 180}deg`
543
- }]
544
- }), [listProgress]);
545
- // Collapsed, the switch card is a single row and reads as a PILL; opened, it
546
- // becomes a card holding rows and takes the grouped-section corner. The corner
547
- // is driven off the SAME `listProgress` as the reveal — but clamped to its
548
- // opening fraction, so it resolves early instead of trailing the rows: the
549
- // card already reads as a card by the time they are visible. Collapsing is the
550
- // mirror image, the pill returning over the closing tail.
551
- const switchCardStyle = useAnimatedStyle(() => ({
552
- borderRadius: interpolate(listProgress.value, [0, SWITCH_CARD_RADIUS_SETTLE], [SWITCH_CARD_PILL_RADIUS, SWITCH_CARD_RADIUS], Extrapolation.CLAMP)
553
- }), [listProgress]);
554
- // `CompositionBar` ships as an interactive breakdown: a selected segment
555
- // replaces its hint line with that segment's readout. Tapping the selected one
556
- // again clears it.
557
- const [storageSegment, setStorageSegment] = useState(null);
558
- const toggleStorageSegment = useCallback(key => setStorageSegment(previous => previous === key ? null : key), []);
559
- const toggleExpanded = useCallback(() => {
560
- const next = !expanded;
561
- setExpanded(next);
562
- listProgress.value = withTiming(next ? 1 : 0, {
563
- duration: 240
564
- });
565
- }, [expanded, listProgress]);
566
- if (snapshot.loading && snapshot.accounts.length === 0) {
567
- return /*#__PURE__*/_jsxs(View, {
568
- className: "items-center justify-center gap-space-12 py-space-24",
569
- children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
570
- name: "loading",
571
- size: 24,
572
- color: theme.colors.textSecondary
573
- }), /*#__PURE__*/_jsx(Text, {
574
- className: "text-body text-text-secondary text-center",
575
- children: t('accountSwitcher.loading')
576
- })]
577
- });
578
- }
579
- const switchingDisabled = snapshot.switchingAccountId !== null;
580
- const current = snapshot.accounts.find(account => account.isCurrent) ?? snapshot.accounts[0];
581
- const others = current ? snapshot.accounts.filter(account => account.accountId !== current.accountId) : snapshot.accounts;
582
- const currentAccent = current ? resolveAccentHex(current.color, theme.colors.primary) : theme.colors.primary;
583
- // The hero's address line under the greeting: the account's canonical @oxy.so
584
- // email when it has one, else its normalized `@handle` (never a synthesized
585
- // `username@oxy.so`, per the identity contract — `getNormalizedUserHandle`).
586
- const currentAddress = current ? heroAddressLine(current) : null;
587
- // The switch list repeats the CURRENT account (first, ringed) — unlike the old
588
- // compact header it is not represented anywhere else once the hero moved out
589
- // of the card, and the list is where you switch back to it.
590
- const switchableAccounts = current ? [current, ...others] : others;
591
- const facepile = switchableAccounts.map(account => ({
592
- id: account.accountId,
593
- uri: account.avatarUrl ?? undefined,
594
- displayName: account.displayName
595
- }));
596
-
597
- // Used vs free is a two-part COMPOSITION (the parts always fill the bar), not
598
- // a progress value — exactly what Bloom's `CompositionBar` models. Both colors
599
- // are theme tokens, so the bar is correct in light and dark.
600
- const storageCategories = storage ? [{
601
- key: 'used',
602
- name: t('accountMenu.storage.used'),
603
- amount: storage.usedBytes,
604
- color: theme.colors.primary
605
- }, {
606
- key: 'free',
607
- name: t('accountMenu.storage.free'),
608
- amount: Math.max(0, storage.limitBytes - storage.usedBytes),
609
- color: theme.colors.contrast50
610
- }] : [];
611
- const usageLabel = storage ? t('accountMenu.storage.usage', {
612
- used: formatStorageGb(storage.usedBytes),
613
- total: formatStorageGb(storage.limitBytes)
614
- }) : t('accountMenu.storage.unavailable');
615
-
616
- // The switch list body, revealed under the "Switch account" row. Own markup,
617
- // not a Bloom grouped section: this is not a list of settings rows and the
618
- // component is not a card container. It mirrors the section's rhythm by hand —
619
- // 12px content inset, 12px after the avatar, a hairline between rows — and
620
- // draws those hairlines INSIDE the animated clip, so a collapsed list never
621
- // strands one against the header row.
622
- const listItems = /*#__PURE__*/_jsxs(_Fragment, {
623
- children: [switchableAccounts.map((account, index) => {
624
- const accent = resolveAccentHex(account.color, theme.colors.primary);
625
- const isSwitching = snapshot.switchingAccountId === account.accountId;
626
- return /*#__PURE__*/_jsxs(Fragment, {
627
- children: [index > 0 ? /*#__PURE__*/_jsx(View, {
628
- className: "h-px bg-border opacity-30 ml-space-12"
629
- }) : null, /*#__PURE__*/_jsxs(HoverPressable, {
630
- baseClassName: `flex-row items-center gap-space-12 px-space-12 py-[10px]${switchingDisabled ? ' opacity-60' : ''}`,
631
- hoverClassName: "bg-fill-secondary",
632
- onPress: () => handlers.onSwitch(account.accountId),
633
- disabled: switchingDisabled,
634
- accessibilityRole: "button",
635
- accessibilityLabel: account.displayName,
636
- children: [/*#__PURE__*/_jsxs(View, {
637
- children: [/*#__PURE__*/_jsx(Avatar, {
638
- source: account.avatarUrl ?? undefined,
639
- variant: "thumb",
640
- name: account.displayName,
641
- size: SWITCH_AVATAR_SIZE
642
- }), account.isCurrent ? /*#__PURE__*/_jsx(View, {
643
- style: [styles.currentAvatarRing, {
644
- borderColor: accent
645
- }],
646
- pointerEvents: "none"
647
- }) : null]
648
- }), /*#__PURE__*/_jsxs(View, {
649
- className: "flex-1 min-w-0",
650
- children: [/*#__PURE__*/_jsx(Text, {
651
- className: "text-body font-semibold text-text",
652
- numberOfLines: 1,
653
- children: account.displayName
654
- }), account.email ? /*#__PURE__*/_jsx(Text, {
655
- className: "text-caption text-text-secondary",
656
- numberOfLines: 1,
657
- children: account.email
658
- }) : null]
659
- }), isSwitching ? /*#__PURE__*/_jsx(MaterialCommunityIcons, {
660
- name: "loading",
661
- size: 20,
662
- color: accent
663
- }) : null]
664
- })]
665
- }, account.accountId);
666
- }), /*#__PURE__*/_jsx(View, {
667
- className: "h-px bg-border opacity-30 ml-space-12"
668
- }), /*#__PURE__*/_jsx(AccountAffordanceRow, {
669
- icon: "plus",
670
- label: t('accountMenu.addAnother'),
671
- onPress: handlers.onAdd,
672
- disabled: switchingDisabled,
673
- theme: theme
674
- }), /*#__PURE__*/_jsx(View, {
675
- className: "h-px bg-border opacity-30 ml-space-12"
676
- }), /*#__PURE__*/_jsx(AccountAffordanceRow, {
677
- icon: "account-multiple-outline",
678
- label: t('accountSwitcher.manageOnDevice'),
679
- onPress: handlers.onManage,
680
- disabled: switchingDisabled,
681
- theme: theme
682
- })]
683
- });
684
- const manageLabel = t('accountMenu.manage');
685
- const switchLabel = t('accountMenu.switchAccount');
686
- return /*#__PURE__*/_jsxs(View, {
687
- children: [/*#__PURE__*/_jsxs(View, {
688
- style: styles.hero,
689
- children: [current ? /*#__PURE__*/_jsxs(_Fragment, {
690
- children: [/*#__PURE__*/_jsxs(PressableScale, {
691
- onPress: handlers.onEditAvatar,
692
- accessibilityRole: "button",
693
- accessibilityLabel: t('editProfile.changeAvatar'),
694
- style: styles.heroAvatarPressable,
695
- children: [/*#__PURE__*/_jsx(Avatar, {
696
- source: current.avatarUrl ?? undefined,
697
- name: current.displayName,
698
- size: HERO_AVATAR_SIZE
699
- }), /*#__PURE__*/_jsx(View, {
700
- style: [styles.heroAvatarRing, {
701
- borderColor: currentAccent
702
- }],
703
- pointerEvents: "none"
704
- }), /*#__PURE__*/_jsx(AvatarCameraBadge, {})]
705
- }), /*#__PURE__*/_jsxs(View, {
706
- style: styles.heroNameBlock,
707
- children: [/*#__PURE__*/_jsx(Text, {
708
- style: [styles.heroGreeting, {
709
- color: theme.colors.text
710
- }],
711
- numberOfLines: 2,
712
- children: t('accountMenu.greeting', {
713
- name: current.displayName
714
- })
715
- }), currentAddress ? /*#__PURE__*/_jsx(Text, {
716
- style: [styles.heroAddress, {
717
- color: theme.colors.textSecondary
718
- }],
719
- numberOfLines: 1,
720
- children: currentAddress
721
- }) : null]
722
- })]
723
- }) : null, /*#__PURE__*/_jsx(Button, {
724
- variant: "secondary",
725
- size: "small",
726
- onPress: handlers.onManage,
727
- accessibilityLabel: manageLabel,
728
- children: manageLabel
729
- })]
730
- }), /*#__PURE__*/_jsxs(Animated.View, {
731
- className: "bg-fill overflow-hidden mb-space-16",
732
- style: switchCardStyle,
733
- children: [/*#__PURE__*/_jsxs(HoverPressable, {
734
- baseClassName: `flex-row items-center gap-space-12 px-space-12 py-[10px] min-h-[44px]${switchingDisabled ? ' opacity-60' : ''}`,
735
- hoverClassName: "bg-fill-secondary",
736
- onPress: toggleExpanded,
737
- disabled: switchingDisabled,
738
- accessibilityRole: "button"
739
- // The ARIA prop, not `accessibilityState`: react-native-web 0.21
740
- // forwards only this one, and RN maps it to
741
- // `accessibilityState.expanded` natively — so the disclosure state
742
- // reaches assistive tech on BOTH platforms.
743
- ,
744
- "aria-expanded": expanded,
745
- accessibilityLabel: switchLabel,
746
- children: [/*#__PURE__*/_jsx(Text, {
747
- className: "flex-1 text-body text-text",
748
- numberOfLines: 1,
749
- children: switchLabel
750
- }), expanded ? null : /*#__PURE__*/_jsx(AvatarGroup, {
751
- items: facepile,
752
- layout: "stack",
753
- size: FACEPILE_AVATAR_SIZE,
754
- max: FACEPILE_MAX,
755
- overlap: FACEPILE_OVERLAP,
756
- variant: "thumb",
757
- showInitials: true,
758
- ringColor: theme.colors.card
759
- }), /*#__PURE__*/_jsx(View, {
760
- style: [styles.chevronCircle, {
761
- backgroundColor: theme.colors.contrast50
762
- }],
763
- children: /*#__PURE__*/_jsx(Animated.View, {
764
- style: chevronStyle,
765
- children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
766
- name: "chevron-down",
767
- size: 20,
768
- color: theme.colors.text
769
- })
770
- })
771
- })]
772
- }), /*#__PURE__*/_jsx(Animated.View, {
773
- style: [styles.collapse, listStyle],
774
- pointerEvents: expanded ? 'auto' : 'none',
775
- children: /*#__PURE__*/_jsx(View, {
776
- style: styles.collapseMeasure,
777
- onLayout: event => setListContentHeight(event.nativeEvent.layout.height),
778
- children: /*#__PURE__*/_jsx(View, {
779
- children: listItems
780
- })
781
- })
782
- })]
783
- }), /*#__PURE__*/_jsxs(View, {
784
- className: "bg-fill rounded-[16px] overflow-hidden mb-space-16 px-space-12 py-[10px] gap-space-12",
785
- children: [/*#__PURE__*/_jsxs(View, {
786
- className: "flex-row items-center gap-space-12 min-h-[24px]",
787
- children: [/*#__PURE__*/_jsx(View, {
788
- className: "w-[20px] items-center",
789
- children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
790
- name: "cloud-outline",
791
- size: ROW_ICON_SIZE,
792
- color: theme.colors.textSecondary
793
- })
794
- }), /*#__PURE__*/_jsx(Text, {
795
- className: "flex-1 text-body font-semibold text-text",
796
- numberOfLines: 1,
797
- children: t('accountMenu.storage.title')
798
- })]
799
- }), /*#__PURE__*/_jsx(CompositionBar, {
800
- categories: storageCategories,
801
- selectedKey: storageSegment,
802
- onSelect: toggleStorageSegment,
803
- hintLabel: usageLabel,
804
- formatReadout: (bytes, percent) => `${formatStorageGb(bytes)} · ${percent}%`
805
- }), /*#__PURE__*/_jsxs(View, {
806
- className: "flex-row gap-space-8",
807
- children: [/*#__PURE__*/_jsx(StorageChip, {
808
- label: t('accountMenu.storage.upgrade'),
809
- onPress: menu.onUpgradeStorage
810
- }), /*#__PURE__*/_jsx(StorageChip, {
811
- label: t('accountMenu.storage.manage'),
812
- onPress: menu.onManageStorage
813
- })]
814
- })]
815
- }), /*#__PURE__*/_jsxs(SettingsListGroup, {
816
- children: [/*#__PURE__*/_jsx(SettingsListItem, {
817
- icon: /*#__PURE__*/_jsx(MenuIcon, {
818
- name: "tray-arrow-down",
819
- theme: theme
820
- }),
821
- title: t('accountMenu.data'),
822
- onPress: menu.onOpenData
823
- }), /*#__PURE__*/_jsx(SettingsListItem, {
824
- icon: /*#__PURE__*/_jsx(MenuIcon, {
825
- name: "cog-outline",
826
- theme: theme
827
- }),
828
- title: t('accountMenu.settings'),
829
- onPress: menu.onOpenSettings
830
- }), /*#__PURE__*/_jsx(SettingsListItem, {
831
- icon: /*#__PURE__*/_jsx(MenuIcon, {
832
- name: "help-circle-outline",
833
- theme: theme
834
- }),
835
- title: t('accountMenu.help'),
836
- onPress: menu.onHelp
837
- }), /*#__PURE__*/_jsx(SettingsListItem, {
838
- icon: /*#__PURE__*/_jsx(MenuIcon, {
839
- name: "logout",
840
- theme: theme
841
- }),
842
- title: t('accountMenu.signOut'),
843
- onPress: menu.onSignOut,
844
- showChevron: false
845
- })]
846
- }), /*#__PURE__*/_jsxs(View, {
847
- className: "flex-row items-center justify-center gap-space-12 px-space-12 pb-space-8",
848
- children: [/*#__PURE__*/_jsx(Pressable, {
849
- onPress: menu.onPrivacy,
850
- accessibilityRole: "link",
851
- children: /*#__PURE__*/_jsx(Text, {
852
- className: "text-bodySmall text-text-secondary",
853
- children: t('accountMenu.privacy')
854
- })
855
- }), /*#__PURE__*/_jsx(Text, {
856
- className: "text-bodySmall text-text-tertiary",
857
- children: "\xB7"
858
- }), /*#__PURE__*/_jsx(Pressable, {
859
- onPress: menu.onTerms,
860
- accessibilityRole: "link",
861
- children: /*#__PURE__*/_jsx(Text, {
862
- className: "text-bodySmall text-text-secondary",
863
- children: t('accountMenu.terms')
864
- })
865
- })]
866
- })]
867
- });
868
- };
869
-
870
- // ---------------------------------------------------------------------------
871
- // Account-menu row building blocks (NativeWind)
872
- // ---------------------------------------------------------------------------
873
-
874
- /**
875
- * An account-list AFFORDANCE row ("Add another account", "Manage accounts on
876
- * this device") — a bordered circle sized to the avatar it stands in for, so its
877
- * label lands on the same line as every account name above it. Own markup, like
878
- * the account rows it closes: this list is not a Bloom grouped section.
879
- */
880
- const AccountAffordanceRow = ({
881
- icon,
882
- label,
883
- onPress,
884
- disabled,
885
- theme
886
- }) => /*#__PURE__*/_jsxs(HoverPressable, {
887
- baseClassName: `flex-row items-center gap-space-12 px-space-12 py-[10px]${disabled ? ' opacity-60' : ''}`,
888
- hoverClassName: "bg-fill-secondary",
889
- onPress: onPress,
890
- disabled: disabled,
891
- accessibilityRole: "button",
892
- accessibilityLabel: label,
893
- children: [/*#__PURE__*/_jsx(View, {
894
- className: "w-[36px] h-[36px] items-center justify-center rounded-radius-max border border-border",
895
- children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
896
- name: icon,
897
- size: BADGE_GLYPH_SIZE,
898
- color: theme.colors.textSecondary
899
- })
900
- }), /*#__PURE__*/_jsx(Text, {
901
- className: "flex-1 text-body font-semibold text-text",
902
- numberOfLines: 1,
903
- children: label
904
- })]
905
- });
906
-
907
- /**
908
- * The leading glyph for a grouped-section menu row, sized to Bloom's 20px icon
909
- * column so the icons, the storage block's cloud and every row title align.
910
- */
911
- const MenuIcon = ({
912
- name,
913
- theme
914
- }) => /*#__PURE__*/_jsx(MaterialCommunityIcons, {
915
- name: name,
916
- size: ROW_ICON_SIZE,
917
- color: theme.colors.textSecondary
918
- });
919
-
920
- /** A storage action chip — a bordered pill on the sheet background. */
921
- const StorageChip = ({
922
- label,
923
- onPress
924
- }) => /*#__PURE__*/_jsx(HoverPressable, {
925
- baseClassName: "rounded-radius-max border border-border bg-bg py-[9px] px-[14px]",
926
- hoverClassName: "bg-fill-secondary",
927
- onPress: onPress,
928
- accessibilityRole: "button",
929
- accessibilityLabel: label,
930
- children: /*#__PURE__*/_jsx(Text, {
931
- className: "text-bodySmall font-semibold text-text",
932
- children: label
933
- })
934
- });
935
- const AccountRow = ({
936
- account,
937
- theme,
938
- switching,
939
- disabled,
940
- onPress
941
- }) => {
942
- const accent = resolveAccentHex(account.color, theme.colors.primary);
943
- const rowStyle = [styles.accountRow, {
944
- borderColor: account.isCurrent ? accent : theme.colors.border,
945
- backgroundColor: theme.colors.card
946
- }, disabled && !switching ? styles.rowDisabled : null];
947
- return /*#__PURE__*/_jsx(BloomColorScope, {
948
- colorPreset: toPreset(account.color),
949
- asChild: true,
950
- children: /*#__PURE__*/_jsxs(Pressable, {
951
- style: rowStyle,
952
- onPress: onPress,
953
- disabled: disabled,
954
- accessibilityRole: "button",
955
- accessibilityState: {
956
- selected: account.isCurrent,
957
- disabled
958
- },
959
- accessibilityLabel: account.displayName,
960
- children: [/*#__PURE__*/_jsx(View, {
961
- style: [styles.avatarRing, {
962
- borderColor: account.isCurrent ? accent : 'transparent'
963
- }],
964
- children: /*#__PURE__*/_jsx(Avatar, {
965
- source: account.avatarUrl ?? undefined,
966
- variant: "thumb",
967
- name: account.displayName,
968
- size: ROW_AVATAR_SIZE
969
- })
970
- }), /*#__PURE__*/_jsxs(View, {
971
- style: styles.rowMeta,
972
- children: [/*#__PURE__*/_jsx(Text, {
973
- style: [styles.rowName, {
974
- color: theme.colors.text
975
- }],
976
- numberOfLines: 1,
977
- children: account.displayName
978
- }), account.email ? /*#__PURE__*/_jsx(Text, {
979
- style: [styles.rowHandle, {
980
- color: theme.colors.textSecondary
981
- }],
982
- numberOfLines: 1,
983
- children: account.email
984
- }) : null]
985
- }), switching ? /*#__PURE__*/_jsx(MaterialCommunityIcons, {
986
- name: "loading",
987
- size: 20,
988
- color: accent
989
- }) : account.isCurrent ? /*#__PURE__*/_jsx(MaterialCommunityIcons, {
990
- name: "check-circle",
991
- size: 20,
992
- color: accent
993
- }) : /*#__PURE__*/_jsx(MaterialCommunityIcons, {
994
- name: "chevron-right",
995
- size: 20,
996
- color: theme.colors.textSecondary
997
- })]
998
- })
999
- });
1000
- };
1001
-
1002
- // ---------------------------------------------------------------------------
1003
- // Sign-in view (add / signin) — NATIVE-facing today: on web `autoStartSignIn`
1004
- // (fired from the subscribe pass / the add / back-to-sign-in handlers) moves the
1005
- // view to `qr` almost immediately, so this renders only for a brief instant there.
1006
- // ---------------------------------------------------------------------------
1007
-
1008
- const SignInView = ({
1009
- snapshot,
1010
- theme,
1011
- t,
1012
- handlers,
1013
- onSignInWithOxy,
1014
- onScanQr,
1015
- onCreateAccount
1016
- }) => /*#__PURE__*/_jsxs(View, {
1017
- style: styles.signInBlock,
1018
- children: [snapshot.accounts.length > 0 ? /*#__PURE__*/_jsxs(View, {
1019
- style: styles.rows,
1020
- children: [snapshot.accounts.map(account => /*#__PURE__*/_jsx(AccountRow, {
1021
- account: account,
1022
- theme: theme,
1023
- switching: snapshot.switchingAccountId === account.accountId,
1024
- disabled: snapshot.switchingAccountId !== null,
1025
- onPress: () => handlers.onSwitch(account.accountId)
1026
- }, account.accountId)), /*#__PURE__*/_jsx(Dividerish, {
1027
- theme: theme,
1028
- label: t('signin.or') || 'or'
1029
- })]
1030
- }) : null, /*#__PURE__*/_jsx(Button, {
1031
- variant: "primary",
1032
- onPress: onSignInWithOxy,
1033
- style: styles.primaryButton,
1034
- children: t('accountSwitcher.signInWithOxy') || 'Sign in with Oxy'
1035
- }), /*#__PURE__*/_jsx(Button, {
1036
- variant: "secondary",
1037
- onPress: onScanQr,
1038
- style: styles.secondaryButton,
1039
- children: t('accountSwitcher.scanQr') || 'Scan a QR from another device'
1040
- }), /*#__PURE__*/_jsx(SignUpFooterLink, {
1041
- theme: theme,
1042
- t: t,
1043
- onPress: onCreateAccount
1044
- })]
1045
- });
1046
- const Dividerish = ({
1047
- theme,
1048
- label
1049
- }) => /*#__PURE__*/_jsxs(View, {
1050
- style: styles.dividerRow,
1051
- children: [/*#__PURE__*/_jsx(View, {
1052
- style: [styles.dividerLine, {
1053
- backgroundColor: theme.colors.border
1054
- }]
1055
- }), /*#__PURE__*/_jsx(Text, {
1056
- style: [styles.dividerText, {
1057
- color: theme.colors.textSecondary
1058
- }],
1059
- children: label
1060
- }), /*#__PURE__*/_jsx(View, {
1061
- style: [styles.dividerLine, {
1062
- backgroundColor: theme.colors.border
1063
- }]
1064
- })]
1065
- });
1066
-
1067
- /** "New to Oxy? Create one" — shared by `SignInView` and `QrView`. */
1068
- const SignUpFooterLink = ({
1069
- theme,
1070
- t,
1071
- onPress
1072
- }) => /*#__PURE__*/_jsx(Pressable, {
1073
- onPress: onPress,
1074
- accessibilityRole: "button",
1075
- style: styles.footerLink,
1076
- children: /*#__PURE__*/_jsx(Text, {
1077
- style: [styles.linkText, {
1078
- color: theme.colors.textSecondary
1079
- }],
1080
- children: t('signin.createAccountLink') || 'New to Oxy? Create one'
1081
- })
1082
- });
1083
-
1084
- /** "Already have an account? Sign in" — used by `SignUpView`. */
1085
- const SignInFooterLink = ({
1086
- theme,
1087
- t,
1088
- onPress
1089
- }) => /*#__PURE__*/_jsx(Pressable, {
1090
- onPress: onPress,
1091
- accessibilityRole: "button",
1092
- style: styles.footerLink,
1093
- children: /*#__PURE__*/_jsx(Text, {
1094
- style: [styles.linkText, {
1095
- color: theme.colors.textSecondary
1096
- }],
1097
- children: t('signup.backToSignInLink') || 'Already have an account? Sign in'
1098
- })
1099
- });
1100
-
1101
- // ---------------------------------------------------------------------------
1102
- // QR view — the PRIMARY web sign-in surface, and the ONLY sign-in surface on
1103
- // native. Commons is ALWAYS the priority path (owner mandate): the QR here
1104
- // and the "Get Commons" CTA below are the leading content everywhere they
1105
- // appear. The passkey link is explicitly the lightweight, de-emphasized
1106
- // alternative for someone who doesn't want to install Commons — same visual
1107
- // subordination (a small text link, never a button) and the same "No
1108
- // Commons?" framing in its copy wherever it's offered.
1109
- // ---------------------------------------------------------------------------
1110
-
1111
- const QrView = ({
1112
- snapshot,
1113
- theme,
1114
- t,
1115
- onRetry,
1116
- passkeyAvailable,
1117
- onSignInWithPasskey,
1118
- passkeyPending,
1119
- onCreateAccount
1120
- }) => {
1121
- const {
1122
- signIn,
1123
- commonsAvailability
1124
- } = snapshot;
1125
- const [showQrAnyway, setShowQrAnyway] = useState(false);
1126
-
1127
- // A ceremony FAILURE is surfaced as a toast by `handleSignInWithPasskey` — the
1128
- // link itself never renders an inline error (owner mandate).
1129
- const passkeyLink = passkeyAvailable && signIn.phase !== 'authorized' ? /*#__PURE__*/_jsx(Pressable, {
1130
- onPress: onSignInWithPasskey,
1131
- disabled: passkeyPending,
1132
- accessibilityRole: "button",
1133
- style: styles.footerLink,
1134
- testID: "passkey-signin-link",
1135
- children: /*#__PURE__*/_jsx(Text, {
1136
- style: [styles.linkText, {
1137
- color: theme.colors.textSecondary
1138
- }],
1139
- children: passkeyPending ? t('accountSwitcher.passkeySigningIn') || 'Signing in…' : t('accountSwitcher.useIdentityOnDevice') || 'No Commons? Use a passkey on this device instead'
1140
- })
1141
- }) : null;
1142
-
1143
- // Native, Commons confirmed NOT installed: a same-device QR is a dead
1144
- // end (the user can't scan their own screen) — lead with "Get Commons"
1145
- // instead, and demote the QR to an explicit "I have it elsewhere" reveal.
1146
- if (commonsAvailability === 'unavailable' && !showQrAnyway) {
1147
- return /*#__PURE__*/_jsxs(View, {
1148
- style: styles.centeredBlock,
1149
- children: [/*#__PURE__*/_jsx(Text, {
1150
- style: [styles.mutedText, {
1151
- color: theme.colors.textSecondary
1152
- }],
1153
- children: t('accountSwitcher.commonsNotInstalled') || "Don't have Commons? Get the app to sign in with your Oxy ID."
1154
- }), /*#__PURE__*/_jsx(Button, {
1155
- variant: "primary",
1156
- onPress: () => void Linking.openURL(getCommonsAcquisitionUrl(Platform.OS)),
1157
- style: styles.primaryButton,
1158
- children: t('accountSwitcher.getCommons') || 'Get Commons'
1159
- }), /*#__PURE__*/_jsx(Pressable, {
1160
- onPress: () => setShowQrAnyway(true),
1161
- accessibilityRole: "button",
1162
- style: styles.footerLink,
1163
- children: /*#__PURE__*/_jsx(Text, {
1164
- style: [styles.linkText, {
1165
- color: theme.colors.textSecondary
1166
- }],
1167
- children: t('accountSwitcher.showQrAnyway') || 'I have Commons on another device'
1168
- })
1169
- }), passkeyLink, /*#__PURE__*/_jsx(SignUpFooterLink, {
1170
- theme: theme,
1171
- t: t,
1172
- onPress: onCreateAccount
1173
- })]
1174
- });
1175
- }
1176
- if (signIn.phase === 'error') {
1177
- // The failure reason is toasted by the controller subscription above — no
1178
- // inline error copy here (owner mandate).
1179
- return /*#__PURE__*/_jsxs(View, {
1180
- style: styles.centeredBlock,
1181
- children: [/*#__PURE__*/_jsx(Button, {
1182
- variant: "secondary",
1183
- onPress: onRetry,
1184
- style: styles.secondaryButton,
1185
- children: t('common.actions.tryAgain') || 'Try again'
1186
- }), passkeyLink]
1187
- });
1188
- }
1189
- if (signIn.phase === 'starting' || signIn.phase === 'authorized' || !signIn.qrPayload) {
1190
- const label = signIn.phase === 'authorized' ? t('signin.status.signingIn') || 'Signing in…' : t('accountSwitcher.loading') || 'Preparing sign-in…';
1191
- return /*#__PURE__*/_jsxs(View, {
1192
- style: styles.centeredBlock,
1193
- children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
1194
- name: "loading",
1195
- size: 26,
1196
- color: theme.colors.primary
1197
- }), /*#__PURE__*/_jsx(Text, {
1198
- style: [styles.mutedText, {
1199
- color: theme.colors.textSecondary
1200
- }],
1201
- children: label
1202
- })]
1203
- });
1204
- }
1205
- return /*#__PURE__*/_jsxs(View, {
1206
- style: styles.centeredBlock,
1207
- children: [/*#__PURE__*/_jsx(Text, {
1208
- style: [styles.qrHeadline, {
1209
- color: theme.colors.text
1210
- }],
1211
- children: t('accountSwitcher.qrHeadline') || 'Sign in with your Oxy identity'
1212
- }), /*#__PURE__*/_jsx(View, {
1213
- style: styles.qrPlate,
1214
- children: /*#__PURE__*/_jsx(QRCode, {
1215
- value: signIn.qrPayload,
1216
- size: QR_SIZE,
1217
- backgroundColor: QR_PLATE_BG,
1218
- color: QR_FOREGROUND
1219
- })
1220
- }), /*#__PURE__*/_jsx(Text, {
1221
- style: [styles.mutedText, {
1222
- color: theme.colors.textSecondary
1223
- }],
1224
- children: t('accountSwitcher.scanWithOxy') || 'Scan with Commons on your phone to continue.'
1225
- }), passkeyLink, /*#__PURE__*/_jsx(SignUpFooterLink, {
1226
- theme: theme,
1227
- t: t,
1228
- onPress: onCreateAccount
1229
- })]
1230
- });
1231
- };
1232
-
1233
- // ---------------------------------------------------------------------------
1234
- // Sign-up view
1235
- // ---------------------------------------------------------------------------
1236
-
1237
- /** Debounced username-availability check over the existing SDK method. */
1238
- function useUsernameAvailability(oxyServices, t) {
1239
- const [status, setStatus] = useState('idle');
1240
- const timerRef = useRef(null);
1241
- const requestSeqRef = useRef(0);
1242
- const check = useCallback(value => {
1243
- if (timerRef.current) clearTimeout(timerRef.current);
1244
- const seq = ++requestSeqRef.current;
1245
- if (!value || value.length < 3) {
1246
- setStatus('idle');
1247
- return;
1248
- }
1249
- setStatus('checking');
1250
- timerRef.current = setTimeout(() => {
1251
- void oxyServices.checkUsernameAvailability(value).then(result => {
1252
- if (seq !== requestSeqRef.current) return; // superseded by a newer check
1253
- setStatus(result.available ? 'available' : 'taken');
1254
- }).catch(() => {
1255
- if (seq !== requestSeqRef.current) return;
1256
- // Reset the (now stale) verdict rather than block on it, and surface
1257
- // the failure as a toast — never an inline error inside the dialog.
1258
- setStatus('idle');
1259
- toast.error(t('accounts.create.username.checkFailed') || 'Could not check availability');
1260
- });
1261
- }, 400);
1262
- }, [oxyServices, t]);
1263
- return {
1264
- status,
1265
- check
1266
- };
1267
- }
1268
- const UsernameStatusText = ({
1269
- status,
1270
- theme,
1271
- t
1272
- }) => {
1273
- if (status === 'idle') return null;
1274
- if (status === 'checking') {
1275
- return /*#__PURE__*/_jsx(Text, {
1276
- style: [styles.mutedText, {
1277
- color: theme.colors.textSecondary
1278
- }],
1279
- children: t('signup.usernameChecking') || 'Checking…'
1280
- });
1281
- }
1282
- if (status === 'available') {
1283
- return /*#__PURE__*/_jsx(Text, {
1284
- style: [styles.mutedText, {
1285
- color: theme.colors.success
1286
- }],
1287
- children: t('signup.usernameAvailable') || 'Available'
1288
- });
1289
- }
1290
- return /*#__PURE__*/_jsx(Text, {
1291
- style: [styles.mutedText, {
1292
- color: theme.colors.error
1293
- }],
1294
- children: t('signup.usernameTaken') || 'This username is taken'
1295
- });
1296
- };
1297
- const SignUpView = ({
1298
- snapshot,
1299
- theme,
1300
- t,
1301
- oxyServices,
1302
- passkeyMode,
1303
- onCreateWithPasskey,
1304
- createPending,
1305
- onOpenHub,
1306
- onBackToSignIn
1307
- }) => {
1308
- const [username, setUsername] = useState('');
1309
- const {
1310
- status: usernameStatus,
1311
- check: checkUsername
1312
- } = useUsernameAvailability(oxyServices, t);
1313
- const canSubmit = username.trim().length >= 3 && usernameStatus === 'available' && !createPending;
1314
-
1315
- // Native — Commons owns identity creation. Mirrors the QR view's own
1316
- // commonsAvailability branch: deep-link straight in when installed, else
1317
- // lead with the same "Get Commons" fallback.
1318
- if (!isWebBrowser()) {
1319
- const commonsInstalled = snapshot.commonsAvailability === 'available';
1320
- return /*#__PURE__*/_jsxs(View, {
1321
- style: styles.centeredBlock,
1322
- children: [/*#__PURE__*/_jsx(Button, {
1323
- variant: "primary",
1324
- onPress: () => void Linking.openURL(commonsInstalled ? COMMONS_CREATE_IDENTITY_URL : getCommonsAcquisitionUrl(Platform.OS)),
1325
- style: styles.primaryButton,
1326
- children: commonsInstalled ? t('signup.createInCommons') || 'Create your identity in Commons' : t('accountSwitcher.getCommons') || 'Get Commons'
1327
- }), /*#__PURE__*/_jsx(SignInFooterLink, {
1328
- theme: theme,
1329
- t: t,
1330
- onPress: onBackToSignIn
1331
- })]
1332
- });
1333
- }
1334
-
1335
- // Web, first-party Oxy origin. Commons leads (owner mandate: it's ALWAYS
1336
- // the priority path, everywhere the two appear) with a "Get Commons" CTA;
1337
- // passkey creation is the de-emphasized alternative underneath for someone
1338
- // who doesn't want to install anything — secondary button, introduced by
1339
- // its own "No Commons?" framing, same subordination as the QR view's link.
1340
- if (passkeyMode === 'direct') {
1341
- return /*#__PURE__*/_jsxs(View, {
1342
- style: styles.signInBlock,
1343
- children: [/*#__PURE__*/_jsx(Text, {
1344
- style: [styles.qrHeadline, {
1345
- color: theme.colors.text
1346
- }],
1347
- children: t('signup.commonsHeadline') || 'Create your identity in Commons'
1348
- }), /*#__PURE__*/_jsx(Text, {
1349
- style: [styles.mutedText, {
1350
- color: theme.colors.textSecondary
1351
- }],
1352
- children: t('signup.commonsExplainer') || 'Commons is your full self-custody Oxy identity — one app, works everywhere.'
1353
- }), /*#__PURE__*/_jsx(Button, {
1354
- variant: "primary",
1355
- onPress: () => void Linking.openURL(getCommonsAcquisitionUrl(Platform.OS)),
1356
- style: styles.primaryButton,
1357
- children: t('accountSwitcher.getCommons') || 'Get Commons'
1358
- }), /*#__PURE__*/_jsx(Dividerish, {
1359
- theme: theme,
1360
- label: t('signin.or') || 'or'
1361
- }), /*#__PURE__*/_jsx(Text, {
1362
- style: [styles.mutedText, {
1363
- color: theme.colors.textSecondary
1364
- }],
1365
- children: t('signup.passkeyAlternative') || "No Commons? Create a passkey on this device instead"
1366
- }), /*#__PURE__*/_jsx(TextInput, {
1367
- style: [styles.usernameInput, {
1368
- borderColor: theme.colors.border,
1369
- color: theme.colors.text
1370
- }],
1371
- placeholder: t('signup.usernamePlaceholder') || 'Choose a username',
1372
- placeholderTextColor: theme.colors.textSecondary,
1373
- value: username,
1374
- autoCapitalize: "none",
1375
- autoCorrect: false,
1376
- autoComplete: "username",
1377
- onChangeText: value => {
1378
- setUsername(value);
1379
- checkUsername(value.trim());
1380
- },
1381
- testID: "signup-username-input"
1382
- }), /*#__PURE__*/_jsx(UsernameStatusText, {
1383
- status: usernameStatus,
1384
- theme: theme,
1385
- t: t
1386
- }), /*#__PURE__*/_jsx(Button, {
1387
- variant: "secondary",
1388
- onPress: () => void onCreateWithPasskey(username.trim()),
1389
- disabled: !canSubmit,
1390
- style: styles.secondaryButton,
1391
- testID: "signup-create-button",
1392
- children: createPending ? t('signup.creating') || 'Creating…' : t('signup.createAccount') || 'Create account'
1393
- }), /*#__PURE__*/_jsx(SignInFooterLink, {
1394
- theme: theme,
1395
- t: t,
1396
- onPress: onBackToSignIn
1397
- })]
1398
- });
1399
- }
1400
-
1401
- // Web, non-Oxy origin (b2): passkey creation can't run locally here — the
1402
- // same WebAuthn RP-ID boundary as sign-in — so this opens the SAME
1403
- // auth.oxy.so passkey hub popup `QrView`'s "No Commons?" link uses.
1404
- // Completing EITHER a sign-in OR a fresh sign-up there relays the resulting
1405
- // session back via the SAME poll/socket engine `showQr` drives.
1406
- return /*#__PURE__*/_jsxs(View, {
1407
- style: styles.centeredBlock,
1408
- children: [/*#__PURE__*/_jsx(Text, {
1409
- style: [styles.mutedText, {
1410
- color: theme.colors.textSecondary
1411
- }],
1412
- children: t('signup.hubExplainer') || 'Create your Oxy ID in a secure window, then come right back.'
1413
- }), /*#__PURE__*/_jsx(Button, {
1414
- variant: "primary",
1415
- onPress: onOpenHub,
1416
- style: styles.primaryButton,
1417
- children: t('signup.continueInWindow') || 'Continue in a new window'
1418
- }), /*#__PURE__*/_jsx(SignInFooterLink, {
1419
- theme: theme,
1420
- t: t,
1421
- onPress: onBackToSignIn
1422
- })]
364
+ onContinueWithOxy: () => void controller.signInWithOxy(),
365
+ alternatives: alternatives
1423
366
  });
1424
367
  };
1425
368
 
@@ -1439,7 +382,12 @@ const EMPTY_SNAPSHOT = {
1439
382
  authorizeCode: null,
1440
383
  qrPayload: null,
1441
384
  expiresAt: null,
1442
- error: null
385
+ error: null,
386
+ route: null,
387
+ routeFailed: false,
388
+ pushSentAt: null,
389
+ openedAt: null,
390
+ progress: 'idle'
1443
391
  },
1444
392
  commonsAvailability: 'unknown'
1445
393
  };