@oxyhq/services 22.9.0 → 22.11.0

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 (584) hide show
  1. package/lib/commonjs/index.js +24 -5
  2. package/lib/commonjs/index.js.map +1 -1
  3. package/lib/commonjs/ui/components/AvatarCameraBadge.js +42 -0
  4. package/lib/commonjs/ui/components/AvatarCameraBadge.js.map +1 -0
  5. package/lib/commonjs/ui/components/{OxyAccountDialog.js → OxyAccountDialogScreen.js} +55 -133
  6. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -0
  7. package/lib/commonjs/ui/components/OxyAuthChooser.js +657 -88
  8. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  9. package/lib/commonjs/ui/components/OxyConsentScreen.js +1 -1
  10. package/lib/commonjs/ui/components/ProfileButton.js +15 -1
  11. package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
  12. package/lib/commonjs/ui/components/ProfileSummaryCard.js +3 -23
  13. package/lib/commonjs/ui/components/ProfileSummaryCard.js.map +1 -1
  14. package/lib/commonjs/ui/components/RequireOxyAuth.js +1 -1
  15. package/lib/commonjs/ui/components/SurfaceHeaderAction.js +63 -0
  16. package/lib/commonjs/ui/components/SurfaceHeaderAction.js.map +1 -0
  17. package/lib/commonjs/ui/components/SurfaceScreen.js +91 -8
  18. package/lib/commonjs/ui/components/SurfaceScreen.js.map +1 -1
  19. package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js +46 -29
  20. package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
  21. package/lib/commonjs/ui/components/modals/DeleteAccountModal.js +47 -23
  22. package/lib/commonjs/ui/components/modals/DeleteAccountModal.js.map +1 -1
  23. package/lib/commonjs/ui/components/oxyAuthChooserStyles.js +81 -19
  24. package/lib/commonjs/ui/components/oxyAuthChooserStyles.js.map +1 -1
  25. package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js +83 -23
  26. package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
  27. package/lib/commonjs/ui/components/surfaces/ActionSheetSurface.js +83 -0
  28. package/lib/commonjs/ui/components/surfaces/ActionSheetSurface.js.map +1 -0
  29. package/lib/commonjs/ui/context/OxyContext.js +79 -29
  30. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  31. package/lib/commonjs/ui/hooks/queries/queryKeys.js +18 -1
  32. package/lib/commonjs/ui/hooks/queries/queryKeys.js.map +1 -1
  33. package/lib/commonjs/ui/hooks/queries/useFileQueries.js +129 -0
  34. package/lib/commonjs/ui/hooks/queries/useFileQueries.js.map +1 -0
  35. package/lib/commonjs/ui/hooks/useAvatarPicker.js +38 -55
  36. package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -1
  37. package/lib/commonjs/ui/hooks/useReduceMotion.js +57 -0
  38. package/lib/commonjs/ui/hooks/useReduceMotion.js.map +1 -0
  39. package/lib/commonjs/ui/hooks/useSurfaceHeader.js +46 -0
  40. package/lib/commonjs/ui/hooks/useSurfaceHeader.js.map +1 -0
  41. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +1 -1
  42. package/lib/commonjs/ui/navigation/accountDialogManager.js +36 -2
  43. package/lib/commonjs/ui/navigation/accountDialogManager.js.map +1 -1
  44. package/lib/commonjs/ui/navigation/bottomSheetManager.js +5 -6
  45. package/lib/commonjs/ui/navigation/bottomSheetManager.js.map +1 -1
  46. package/lib/commonjs/ui/navigation/routes.js +4 -3
  47. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  48. package/lib/commonjs/ui/navigation/surfaceBackBridge.js +68 -0
  49. package/lib/commonjs/ui/navigation/surfaceBackBridge.js.map +1 -0
  50. package/lib/commonjs/ui/navigation/surfaceNavStack.js +62 -15
  51. package/lib/commonjs/ui/navigation/surfaceNavStack.js.map +1 -1
  52. package/lib/commonjs/ui/navigation/surfaceRegistry.js +84 -19
  53. package/lib/commonjs/ui/navigation/surfaceRegistry.js.map +1 -1
  54. package/lib/commonjs/ui/navigation/surfaces.js +139 -25
  55. package/lib/commonjs/ui/navigation/surfaces.js.map +1 -1
  56. package/lib/commonjs/ui/screens/AccountMembersScreen.js +214 -283
  57. package/lib/commonjs/ui/screens/AccountMembersScreen.js.map +1 -1
  58. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +88 -118
  59. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  60. package/lib/commonjs/ui/screens/AccountVerificationScreen.js +22 -36
  61. package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
  62. package/lib/commonjs/ui/screens/AppInfoScreen.js +219 -226
  63. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  64. package/lib/commonjs/ui/screens/AvatarCropScreen.js +287 -289
  65. package/lib/commonjs/ui/screens/AvatarCropScreen.js.map +1 -1
  66. package/lib/commonjs/ui/screens/ChangeAvatarScreen.js +301 -0
  67. package/lib/commonjs/ui/screens/ChangeAvatarScreen.js.map +1 -0
  68. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js +24 -39
  69. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js.map +1 -1
  70. package/lib/commonjs/ui/screens/CreateAccountScreen.js +136 -158
  71. package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
  72. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +29 -36
  73. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  74. package/lib/commonjs/ui/screens/EditProfileScreen.js +101 -109
  75. package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -1
  76. package/lib/commonjs/ui/screens/FAQScreen.js +10 -15
  77. package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
  78. package/lib/commonjs/ui/screens/FeedbackScreen.js +8 -16
  79. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  80. package/lib/commonjs/ui/screens/FileManagementScreen.js +403 -627
  81. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  82. package/lib/commonjs/ui/screens/HelpSupportScreen.js +62 -69
  83. package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
  84. package/lib/commonjs/ui/screens/HistoryViewScreen.js +63 -79
  85. package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
  86. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +69 -98
  87. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  88. package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js +8 -14
  89. package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
  90. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +77 -94
  91. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
  92. package/lib/commonjs/ui/screens/ManageAccountScreen.js +99 -134
  93. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  94. package/lib/commonjs/ui/screens/NotificationsScreen.js +69 -76
  95. package/lib/commonjs/ui/screens/NotificationsScreen.js.map +1 -1
  96. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +3 -8
  97. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  98. package/lib/commonjs/ui/screens/PreferencesScreen.js +67 -74
  99. package/lib/commonjs/ui/screens/PreferencesScreen.js.map +1 -1
  100. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +55 -91
  101. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  102. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +291 -304
  103. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  104. package/lib/commonjs/ui/screens/ProfileScreen.js +100 -114
  105. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  106. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +38 -45
  107. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
  108. package/lib/commonjs/ui/screens/SearchSettingsScreen.js +44 -57
  109. package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -1
  110. package/lib/commonjs/ui/screens/UserLinksScreen.js +24 -31
  111. package/lib/commonjs/ui/screens/UserLinksScreen.js.map +1 -1
  112. package/lib/commonjs/ui/screens/UserListScreen.js +14 -24
  113. package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
  114. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +16 -48
  115. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  116. package/lib/commonjs/ui/screens/fileManagement/FileLibraryError.js +63 -0
  117. package/lib/commonjs/ui/screens/fileManagement/FileLibraryError.js.map +1 -0
  118. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +54 -41
  119. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  120. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js +44 -81
  121. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  122. package/lib/commonjs/ui/screens/trust/TrustAboutScreen.js +66 -75
  123. package/lib/commonjs/ui/screens/trust/TrustAboutScreen.js.map +1 -1
  124. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +111 -139
  125. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  126. package/lib/commonjs/ui/screens/trust/TrustFAQScreen.js +13 -20
  127. package/lib/commonjs/ui/screens/trust/TrustFAQScreen.js.map +1 -1
  128. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +14 -27
  129. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  130. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +68 -85
  131. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  132. package/lib/commonjs/ui/screens/trust/TrustRulesScreen.js +28 -36
  133. package/lib/commonjs/ui/screens/trust/TrustRulesScreen.js.map +1 -1
  134. package/lib/commonjs/ui/stores/resetSessionScopedStores.js +8 -3
  135. package/lib/commonjs/ui/stores/resetSessionScopedStores.js.map +1 -1
  136. package/lib/commonjs/ui/utils/avatarUtils.js +11 -2
  137. package/lib/commonjs/ui/utils/avatarUtils.js.map +1 -1
  138. package/lib/commonjs/ui/utils/fileManagement.js +0 -79
  139. package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
  140. package/lib/module/index.js +12 -5
  141. package/lib/module/index.js.map +1 -1
  142. package/lib/module/ui/components/AvatarCameraBadge.js +40 -0
  143. package/lib/module/ui/components/AvatarCameraBadge.js.map +1 -0
  144. package/lib/module/ui/components/{OxyAccountDialog.js → OxyAccountDialogScreen.js} +57 -135
  145. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -0
  146. package/lib/module/ui/components/OxyAuthChooser.js +659 -91
  147. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  148. package/lib/module/ui/components/OxyConsentScreen.js +1 -1
  149. package/lib/module/ui/components/ProfileButton.js +16 -2
  150. package/lib/module/ui/components/ProfileButton.js.map +1 -1
  151. package/lib/module/ui/components/ProfileSummaryCard.js +2 -23
  152. package/lib/module/ui/components/ProfileSummaryCard.js.map +1 -1
  153. package/lib/module/ui/components/RequireOxyAuth.js +1 -1
  154. package/lib/module/ui/components/SurfaceHeaderAction.js +58 -0
  155. package/lib/module/ui/components/SurfaceHeaderAction.js.map +1 -0
  156. package/lib/module/ui/components/SurfaceScreen.js +93 -10
  157. package/lib/module/ui/components/SurfaceScreen.js.map +1 -1
  158. package/lib/module/ui/components/fileManagement/FileDetailsModal.js +46 -29
  159. package/lib/module/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
  160. package/lib/module/ui/components/modals/DeleteAccountModal.js +46 -23
  161. package/lib/module/ui/components/modals/DeleteAccountModal.js.map +1 -1
  162. package/lib/module/ui/components/oxyAuthChooserStyles.js +81 -19
  163. package/lib/module/ui/components/oxyAuthChooserStyles.js.map +1 -1
  164. package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js +83 -25
  165. package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
  166. package/lib/module/ui/components/surfaces/ActionSheetSurface.js +78 -0
  167. package/lib/module/ui/components/surfaces/ActionSheetSurface.js.map +1 -0
  168. package/lib/module/ui/context/OxyContext.js +80 -30
  169. package/lib/module/ui/context/OxyContext.js.map +1 -1
  170. package/lib/module/ui/hooks/queries/queryKeys.js +16 -0
  171. package/lib/module/ui/hooks/queries/queryKeys.js.map +1 -1
  172. package/lib/module/ui/hooks/queries/useFileQueries.js +120 -0
  173. package/lib/module/ui/hooks/queries/useFileQueries.js.map +1 -0
  174. package/lib/module/ui/hooks/useAvatarPicker.js +38 -55
  175. package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -1
  176. package/lib/module/ui/hooks/useReduceMotion.js +53 -0
  177. package/lib/module/ui/hooks/useReduceMotion.js.map +1 -0
  178. package/lib/module/ui/hooks/useSurfaceHeader.js +42 -0
  179. package/lib/module/ui/hooks/useSurfaceHeader.js.map +1 -0
  180. package/lib/module/ui/hooks/useSwitchableAccounts.js +1 -1
  181. package/lib/module/ui/navigation/accountDialogManager.js +34 -2
  182. package/lib/module/ui/navigation/accountDialogManager.js.map +1 -1
  183. package/lib/module/ui/navigation/bottomSheetManager.js +6 -7
  184. package/lib/module/ui/navigation/bottomSheetManager.js.map +1 -1
  185. package/lib/module/ui/navigation/routes.js +4 -3
  186. package/lib/module/ui/navigation/routes.js.map +1 -1
  187. package/lib/module/ui/navigation/surfaceBackBridge.js +63 -0
  188. package/lib/module/ui/navigation/surfaceBackBridge.js.map +1 -0
  189. package/lib/module/ui/navigation/surfaceNavStack.js +62 -15
  190. package/lib/module/ui/navigation/surfaceNavStack.js.map +1 -1
  191. package/lib/module/ui/navigation/surfaceRegistry.js +84 -19
  192. package/lib/module/ui/navigation/surfaceRegistry.js.map +1 -1
  193. package/lib/module/ui/navigation/surfaces.js +138 -26
  194. package/lib/module/ui/navigation/surfaces.js.map +1 -1
  195. package/lib/module/ui/screens/AccountMembersScreen.js +218 -286
  196. package/lib/module/ui/screens/AccountMembersScreen.js.map +1 -1
  197. package/lib/module/ui/screens/AccountSettingsScreen.js +92 -121
  198. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  199. package/lib/module/ui/screens/AccountVerificationScreen.js +25 -38
  200. package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
  201. package/lib/module/ui/screens/AppInfoScreen.js +220 -227
  202. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  203. package/lib/module/ui/screens/AvatarCropScreen.js +289 -291
  204. package/lib/module/ui/screens/AvatarCropScreen.js.map +1 -1
  205. package/lib/module/ui/screens/ChangeAvatarScreen.js +298 -0
  206. package/lib/module/ui/screens/ChangeAvatarScreen.js.map +1 -0
  207. package/lib/module/ui/screens/ConnectedAppsScreen.js +26 -40
  208. package/lib/module/ui/screens/ConnectedAppsScreen.js.map +1 -1
  209. package/lib/module/ui/screens/CreateAccountScreen.js +139 -160
  210. package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
  211. package/lib/module/ui/screens/EditProfileFieldScreen.js +32 -38
  212. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  213. package/lib/module/ui/screens/EditProfileScreen.js +102 -110
  214. package/lib/module/ui/screens/EditProfileScreen.js.map +1 -1
  215. package/lib/module/ui/screens/FAQScreen.js +11 -15
  216. package/lib/module/ui/screens/FAQScreen.js.map +1 -1
  217. package/lib/module/ui/screens/FeedbackScreen.js +10 -17
  218. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  219. package/lib/module/ui/screens/FileManagementScreen.js +408 -631
  220. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  221. package/lib/module/ui/screens/HelpSupportScreen.js +64 -70
  222. package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
  223. package/lib/module/ui/screens/HistoryViewScreen.js +65 -81
  224. package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
  225. package/lib/module/ui/screens/LanguageSelectorScreen.js +71 -99
  226. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  227. package/lib/module/ui/screens/LearnMoreUsernamesScreen.js +10 -15
  228. package/lib/module/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
  229. package/lib/module/ui/screens/LegalDocumentsScreen.js +78 -94
  230. package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
  231. package/lib/module/ui/screens/ManageAccountScreen.js +102 -137
  232. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  233. package/lib/module/ui/screens/NotificationsScreen.js +71 -77
  234. package/lib/module/ui/screens/NotificationsScreen.js.map +1 -1
  235. package/lib/module/ui/screens/PaymentGatewayScreen.js +4 -9
  236. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  237. package/lib/module/ui/screens/PreferencesScreen.js +69 -75
  238. package/lib/module/ui/screens/PreferencesScreen.js.map +1 -1
  239. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +58 -93
  240. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  241. package/lib/module/ui/screens/PrivacySettingsScreen.js +293 -305
  242. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  243. package/lib/module/ui/screens/ProfileScreen.js +102 -116
  244. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  245. package/lib/module/ui/screens/SavesCollectionsScreen.js +40 -46
  246. package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
  247. package/lib/module/ui/screens/SearchSettingsScreen.js +46 -58
  248. package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -1
  249. package/lib/module/ui/screens/UserLinksScreen.js +26 -32
  250. package/lib/module/ui/screens/UserLinksScreen.js.map +1 -1
  251. package/lib/module/ui/screens/UserListScreen.js +14 -24
  252. package/lib/module/ui/screens/UserListScreen.js.map +1 -1
  253. package/lib/module/ui/screens/WelcomeNewUserScreen.js +17 -49
  254. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  255. package/lib/module/ui/screens/fileManagement/FileLibraryError.js +59 -0
  256. package/lib/module/ui/screens/fileManagement/FileLibraryError.js.map +1 -0
  257. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +54 -42
  258. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  259. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js +45 -81
  260. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  261. package/lib/module/ui/screens/trust/TrustAboutScreen.js +67 -75
  262. package/lib/module/ui/screens/trust/TrustAboutScreen.js.map +1 -1
  263. package/lib/module/ui/screens/trust/TrustCenterScreen.js +112 -139
  264. package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  265. package/lib/module/ui/screens/trust/TrustFAQScreen.js +15 -21
  266. package/lib/module/ui/screens/trust/TrustFAQScreen.js.map +1 -1
  267. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +14 -26
  268. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  269. package/lib/module/ui/screens/trust/TrustRewardsScreen.js +69 -85
  270. package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  271. package/lib/module/ui/screens/trust/TrustRulesScreen.js +30 -37
  272. package/lib/module/ui/screens/trust/TrustRulesScreen.js.map +1 -1
  273. package/lib/module/ui/stores/resetSessionScopedStores.js +8 -3
  274. package/lib/module/ui/stores/resetSessionScopedStores.js.map +1 -1
  275. package/lib/module/ui/utils/avatarUtils.js +11 -2
  276. package/lib/module/ui/utils/avatarUtils.js.map +1 -1
  277. package/lib/module/ui/utils/fileManagement.js +0 -78
  278. package/lib/module/ui/utils/fileManagement.js.map +1 -1
  279. package/lib/typescript/commonjs/index.d.ts +2 -0
  280. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  281. package/lib/typescript/commonjs/ui/components/AvatarCameraBadge.d.ts +4 -0
  282. package/lib/typescript/commonjs/ui/components/AvatarCameraBadge.d.ts.map +1 -0
  283. package/lib/typescript/{module/ui/components/OxyAccountDialog.d.ts → commonjs/ui/components/OxyAccountDialogScreen.d.ts} +5 -4
  284. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -0
  285. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts +3 -3
  286. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  287. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts +2 -2
  288. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
  289. package/lib/typescript/commonjs/ui/components/ProfileSummaryCard.d.ts.map +1 -1
  290. package/lib/typescript/commonjs/ui/components/RequireOxyAuth.d.ts +1 -1
  291. package/lib/typescript/commonjs/ui/components/SurfaceHeaderAction.d.ts +16 -0
  292. package/lib/typescript/commonjs/ui/components/SurfaceHeaderAction.d.ts.map +1 -0
  293. package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts +3 -4
  294. package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts.map +1 -1
  295. package/lib/typescript/commonjs/ui/components/fileManagement/FileDetailsModal.d.ts +14 -4
  296. package/lib/typescript/commonjs/ui/components/fileManagement/FileDetailsModal.d.ts.map +1 -1
  297. package/lib/typescript/commonjs/ui/components/modals/DeleteAccountModal.d.ts +17 -2
  298. package/lib/typescript/commonjs/ui/components/modals/DeleteAccountModal.d.ts.map +1 -1
  299. package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts +75 -13
  300. package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts.map +1 -1
  301. package/lib/typescript/commonjs/ui/components/photogrid/JustifiedPhotoGrid.d.ts +10 -8
  302. package/lib/typescript/commonjs/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -1
  303. package/lib/typescript/commonjs/ui/components/surfaces/ActionSheetSurface.d.ts +38 -0
  304. package/lib/typescript/commonjs/ui/components/surfaces/ActionSheetSurface.d.ts.map +1 -0
  305. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  306. package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts +9 -0
  307. package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts.map +1 -1
  308. package/lib/typescript/commonjs/ui/hooks/queries/useFileQueries.d.ts +50 -0
  309. package/lib/typescript/commonjs/ui/hooks/queries/useFileQueries.d.ts.map +1 -0
  310. package/lib/typescript/commonjs/ui/hooks/useAvatarPicker.d.ts +17 -16
  311. package/lib/typescript/commonjs/ui/hooks/useAvatarPicker.d.ts.map +1 -1
  312. package/lib/typescript/commonjs/ui/hooks/useReduceMotion.d.ts +14 -0
  313. package/lib/typescript/commonjs/ui/hooks/useReduceMotion.d.ts.map +1 -0
  314. package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts +31 -0
  315. package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts.map +1 -0
  316. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts +1 -1
  317. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts +27 -2
  318. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts.map +1 -1
  319. package/lib/typescript/commonjs/ui/navigation/bottomSheetManager.d.ts +4 -5
  320. package/lib/typescript/commonjs/ui/navigation/bottomSheetManager.d.ts.map +1 -1
  321. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
  322. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  323. package/lib/typescript/commonjs/ui/navigation/surfaceBackBridge.d.ts +16 -0
  324. package/lib/typescript/commonjs/ui/navigation/surfaceBackBridge.d.ts.map +1 -0
  325. package/lib/typescript/commonjs/ui/navigation/surfaceNavStack.d.ts +21 -0
  326. package/lib/typescript/commonjs/ui/navigation/surfaceNavStack.d.ts.map +1 -1
  327. package/lib/typescript/commonjs/ui/navigation/surfaceRegistry.d.ts +101 -23
  328. package/lib/typescript/commonjs/ui/navigation/surfaceRegistry.d.ts.map +1 -1
  329. package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts +42 -11
  330. package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts.map +1 -1
  331. package/lib/typescript/commonjs/ui/screens/AccountMembersScreen.d.ts.map +1 -1
  332. package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  333. package/lib/typescript/commonjs/ui/screens/AccountVerificationScreen.d.ts.map +1 -1
  334. package/lib/typescript/commonjs/ui/screens/AppInfoScreen.d.ts.map +1 -1
  335. package/lib/typescript/commonjs/ui/screens/AvatarCropScreen.d.ts +18 -9
  336. package/lib/typescript/commonjs/ui/screens/AvatarCropScreen.d.ts.map +1 -1
  337. package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts +34 -0
  338. package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts.map +1 -0
  339. package/lib/typescript/commonjs/ui/screens/ConnectedAppsScreen.d.ts.map +1 -1
  340. package/lib/typescript/commonjs/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  341. package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  342. package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -1
  343. package/lib/typescript/commonjs/ui/screens/FAQScreen.d.ts.map +1 -1
  344. package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
  345. package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
  346. package/lib/typescript/commonjs/ui/screens/HelpSupportScreen.d.ts.map +1 -1
  347. package/lib/typescript/commonjs/ui/screens/HistoryViewScreen.d.ts.map +1 -1
  348. package/lib/typescript/commonjs/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
  349. package/lib/typescript/commonjs/ui/screens/LearnMoreUsernamesScreen.d.ts.map +1 -1
  350. package/lib/typescript/commonjs/ui/screens/LegalDocumentsScreen.d.ts.map +1 -1
  351. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts +1 -1
  352. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  353. package/lib/typescript/commonjs/ui/screens/NotificationsScreen.d.ts.map +1 -1
  354. package/lib/typescript/commonjs/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  355. package/lib/typescript/commonjs/ui/screens/PreferencesScreen.d.ts.map +1 -1
  356. package/lib/typescript/commonjs/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
  357. package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  358. package/lib/typescript/commonjs/ui/screens/ProfileScreen.d.ts.map +1 -1
  359. package/lib/typescript/commonjs/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
  360. package/lib/typescript/commonjs/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
  361. package/lib/typescript/commonjs/ui/screens/UserLinksScreen.d.ts.map +1 -1
  362. package/lib/typescript/commonjs/ui/screens/UserListScreen.d.ts.map +1 -1
  363. package/lib/typescript/commonjs/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  364. package/lib/typescript/commonjs/ui/screens/fileManagement/FileLibraryError.d.ts +23 -0
  365. package/lib/typescript/commonjs/ui/screens/fileManagement/FileLibraryError.d.ts.map +1 -0
  366. package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts +4 -0
  367. package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
  368. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +10 -2
  369. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  370. package/lib/typescript/commonjs/ui/screens/trust/TrustAboutScreen.d.ts.map +1 -1
  371. package/lib/typescript/commonjs/ui/screens/trust/TrustCenterScreen.d.ts.map +1 -1
  372. package/lib/typescript/commonjs/ui/screens/trust/TrustFAQScreen.d.ts.map +1 -1
  373. package/lib/typescript/commonjs/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  374. package/lib/typescript/commonjs/ui/screens/trust/TrustRewardsScreen.d.ts.map +1 -1
  375. package/lib/typescript/commonjs/ui/screens/trust/TrustRulesScreen.d.ts.map +1 -1
  376. package/lib/typescript/commonjs/ui/stores/resetSessionScopedStores.d.ts +8 -1
  377. package/lib/typescript/commonjs/ui/stores/resetSessionScopedStores.d.ts.map +1 -1
  378. package/lib/typescript/commonjs/ui/types/navigation.d.ts +10 -0
  379. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  380. package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts.map +1 -1
  381. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +0 -48
  382. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
  383. package/lib/typescript/module/index.d.ts +2 -0
  384. package/lib/typescript/module/index.d.ts.map +1 -1
  385. package/lib/typescript/module/ui/components/AvatarCameraBadge.d.ts +4 -0
  386. package/lib/typescript/module/ui/components/AvatarCameraBadge.d.ts.map +1 -0
  387. package/lib/typescript/{commonjs/ui/components/OxyAccountDialog.d.ts → module/ui/components/OxyAccountDialogScreen.d.ts} +5 -4
  388. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -0
  389. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts +3 -3
  390. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  391. package/lib/typescript/module/ui/components/ProfileButton.d.ts +2 -2
  392. package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
  393. package/lib/typescript/module/ui/components/ProfileSummaryCard.d.ts.map +1 -1
  394. package/lib/typescript/module/ui/components/RequireOxyAuth.d.ts +1 -1
  395. package/lib/typescript/module/ui/components/SurfaceHeaderAction.d.ts +16 -0
  396. package/lib/typescript/module/ui/components/SurfaceHeaderAction.d.ts.map +1 -0
  397. package/lib/typescript/module/ui/components/SurfaceScreen.d.ts +3 -4
  398. package/lib/typescript/module/ui/components/SurfaceScreen.d.ts.map +1 -1
  399. package/lib/typescript/module/ui/components/fileManagement/FileDetailsModal.d.ts +14 -4
  400. package/lib/typescript/module/ui/components/fileManagement/FileDetailsModal.d.ts.map +1 -1
  401. package/lib/typescript/module/ui/components/modals/DeleteAccountModal.d.ts +17 -2
  402. package/lib/typescript/module/ui/components/modals/DeleteAccountModal.d.ts.map +1 -1
  403. package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts +75 -13
  404. package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts.map +1 -1
  405. package/lib/typescript/module/ui/components/photogrid/JustifiedPhotoGrid.d.ts +10 -8
  406. package/lib/typescript/module/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -1
  407. package/lib/typescript/module/ui/components/surfaces/ActionSheetSurface.d.ts +38 -0
  408. package/lib/typescript/module/ui/components/surfaces/ActionSheetSurface.d.ts.map +1 -0
  409. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  410. package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts +9 -0
  411. package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts.map +1 -1
  412. package/lib/typescript/module/ui/hooks/queries/useFileQueries.d.ts +50 -0
  413. package/lib/typescript/module/ui/hooks/queries/useFileQueries.d.ts.map +1 -0
  414. package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts +17 -16
  415. package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts.map +1 -1
  416. package/lib/typescript/module/ui/hooks/useReduceMotion.d.ts +14 -0
  417. package/lib/typescript/module/ui/hooks/useReduceMotion.d.ts.map +1 -0
  418. package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts +31 -0
  419. package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts.map +1 -0
  420. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts +1 -1
  421. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts +27 -2
  422. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts.map +1 -1
  423. package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts +4 -5
  424. package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts.map +1 -1
  425. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  426. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  427. package/lib/typescript/module/ui/navigation/surfaceBackBridge.d.ts +16 -0
  428. package/lib/typescript/module/ui/navigation/surfaceBackBridge.d.ts.map +1 -0
  429. package/lib/typescript/module/ui/navigation/surfaceNavStack.d.ts +21 -0
  430. package/lib/typescript/module/ui/navigation/surfaceNavStack.d.ts.map +1 -1
  431. package/lib/typescript/module/ui/navigation/surfaceRegistry.d.ts +101 -23
  432. package/lib/typescript/module/ui/navigation/surfaceRegistry.d.ts.map +1 -1
  433. package/lib/typescript/module/ui/navigation/surfaces.d.ts +42 -11
  434. package/lib/typescript/module/ui/navigation/surfaces.d.ts.map +1 -1
  435. package/lib/typescript/module/ui/screens/AccountMembersScreen.d.ts.map +1 -1
  436. package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  437. package/lib/typescript/module/ui/screens/AccountVerificationScreen.d.ts.map +1 -1
  438. package/lib/typescript/module/ui/screens/AppInfoScreen.d.ts.map +1 -1
  439. package/lib/typescript/module/ui/screens/AvatarCropScreen.d.ts +18 -9
  440. package/lib/typescript/module/ui/screens/AvatarCropScreen.d.ts.map +1 -1
  441. package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts +34 -0
  442. package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts.map +1 -0
  443. package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts.map +1 -1
  444. package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  445. package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  446. package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -1
  447. package/lib/typescript/module/ui/screens/FAQScreen.d.ts.map +1 -1
  448. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
  449. package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
  450. package/lib/typescript/module/ui/screens/HelpSupportScreen.d.ts.map +1 -1
  451. package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
  452. package/lib/typescript/module/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
  453. package/lib/typescript/module/ui/screens/LearnMoreUsernamesScreen.d.ts.map +1 -1
  454. package/lib/typescript/module/ui/screens/LegalDocumentsScreen.d.ts.map +1 -1
  455. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts +1 -1
  456. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  457. package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts.map +1 -1
  458. package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  459. package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts.map +1 -1
  460. package/lib/typescript/module/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
  461. package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  462. package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
  463. package/lib/typescript/module/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
  464. package/lib/typescript/module/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
  465. package/lib/typescript/module/ui/screens/UserLinksScreen.d.ts.map +1 -1
  466. package/lib/typescript/module/ui/screens/UserListScreen.d.ts.map +1 -1
  467. package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  468. package/lib/typescript/module/ui/screens/fileManagement/FileLibraryError.d.ts +23 -0
  469. package/lib/typescript/module/ui/screens/fileManagement/FileLibraryError.d.ts.map +1 -0
  470. package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts +4 -0
  471. package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
  472. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +10 -2
  473. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  474. package/lib/typescript/module/ui/screens/trust/TrustAboutScreen.d.ts.map +1 -1
  475. package/lib/typescript/module/ui/screens/trust/TrustCenterScreen.d.ts.map +1 -1
  476. package/lib/typescript/module/ui/screens/trust/TrustFAQScreen.d.ts.map +1 -1
  477. package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  478. package/lib/typescript/module/ui/screens/trust/TrustRewardsScreen.d.ts.map +1 -1
  479. package/lib/typescript/module/ui/screens/trust/TrustRulesScreen.d.ts.map +1 -1
  480. package/lib/typescript/module/ui/stores/resetSessionScopedStores.d.ts +8 -1
  481. package/lib/typescript/module/ui/stores/resetSessionScopedStores.d.ts.map +1 -1
  482. package/lib/typescript/module/ui/types/navigation.d.ts +10 -0
  483. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  484. package/lib/typescript/module/ui/utils/avatarUtils.d.ts.map +1 -1
  485. package/lib/typescript/module/ui/utils/fileManagement.d.ts +0 -48
  486. package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
  487. package/package.json +9 -5
  488. package/src/index.ts +12 -5
  489. package/src/ui/components/AvatarCameraBadge.tsx +35 -0
  490. package/src/ui/components/{OxyAccountDialog.tsx → OxyAccountDialogScreen.tsx} +50 -116
  491. package/src/ui/components/OxyAuthChooser.tsx +743 -86
  492. package/src/ui/components/OxyConsentScreen.tsx +1 -1
  493. package/src/ui/components/ProfileButton.tsx +18 -3
  494. package/src/ui/components/ProfileSummaryCard.tsx +2 -25
  495. package/src/ui/components/RequireOxyAuth.tsx +1 -1
  496. package/src/ui/components/SurfaceHeaderAction.tsx +60 -0
  497. package/src/ui/components/SurfaceScreen.tsx +108 -14
  498. package/src/ui/components/fileManagement/FileDetailsModal.tsx +50 -36
  499. package/src/ui/components/modals/DeleteAccountModal.tsx +47 -26
  500. package/src/ui/components/oxyAuthChooserStyles.ts +78 -16
  501. package/src/ui/components/photogrid/JustifiedPhotoGrid.tsx +158 -84
  502. package/src/ui/components/photogrid/__tests__/chunkPhotos.test.ts +51 -0
  503. package/src/ui/components/surfaces/ActionSheetSurface.tsx +98 -0
  504. package/src/ui/context/OxyContext.tsx +79 -25
  505. package/src/ui/hooks/queries/queryKeys.ts +15 -0
  506. package/src/ui/hooks/queries/useFileQueries.ts +162 -0
  507. package/src/ui/hooks/useAvatarPicker.ts +46 -74
  508. package/src/ui/hooks/useReduceMotion.ts +58 -0
  509. package/src/ui/hooks/useSurfaceHeader.ts +57 -0
  510. package/src/ui/hooks/useSwitchableAccounts.ts +1 -1
  511. package/src/ui/navigation/__tests__/getSurfaceConfig.test.ts +55 -7
  512. package/src/ui/navigation/__tests__/surfaceNavStack.test.ts +149 -0
  513. package/src/ui/navigation/accountDialogManager.ts +42 -2
  514. package/src/ui/navigation/bottomSheetManager.ts +6 -7
  515. package/src/ui/navigation/routes.ts +6 -4
  516. package/src/ui/navigation/surfaceBackBridge.ts +69 -0
  517. package/src/ui/navigation/surfaceNavStack.ts +72 -9
  518. package/src/ui/navigation/surfaceRegistry.ts +164 -24
  519. package/src/ui/navigation/surfaces.ts +137 -30
  520. package/src/ui/screens/AccountMembersScreen.tsx +39 -100
  521. package/src/ui/screens/AccountSettingsScreen.tsx +32 -54
  522. package/src/ui/screens/AccountVerificationScreen.tsx +23 -51
  523. package/src/ui/screens/AppInfoScreen.tsx +6 -13
  524. package/src/ui/screens/AvatarCropScreen.tsx +340 -311
  525. package/src/ui/screens/ChangeAvatarScreen.tsx +359 -0
  526. package/src/ui/screens/ConnectedAppsScreen.tsx +39 -60
  527. package/src/ui/screens/CreateAccountScreen.tsx +13 -39
  528. package/src/ui/screens/EditProfileFieldScreen.tsx +30 -48
  529. package/src/ui/screens/EditProfileScreen.tsx +7 -16
  530. package/src/ui/screens/FAQScreen.tsx +9 -13
  531. package/src/ui/screens/FeedbackScreen.tsx +8 -22
  532. package/src/ui/screens/FileManagementScreen.tsx +370 -610
  533. package/src/ui/screens/HelpSupportScreen.tsx +7 -13
  534. package/src/ui/screens/HistoryViewScreen.tsx +26 -31
  535. package/src/ui/screens/LanguageSelectorScreen.tsx +12 -46
  536. package/src/ui/screens/LearnMoreUsernamesScreen.tsx +8 -16
  537. package/src/ui/screens/LegalDocumentsScreen.tsx +7 -22
  538. package/src/ui/screens/ManageAccountScreen.tsx +96 -165
  539. package/src/ui/screens/NotificationsScreen.tsx +7 -13
  540. package/src/ui/screens/PaymentGatewayScreen.tsx +3 -10
  541. package/src/ui/screens/PreferencesScreen.tsx +7 -13
  542. package/src/ui/screens/PremiumSubscriptionScreen.tsx +52 -90
  543. package/src/ui/screens/PrivacySettingsScreen.tsx +9 -21
  544. package/src/ui/screens/ProfileScreen.tsx +9 -11
  545. package/src/ui/screens/SavesCollectionsScreen.tsx +7 -13
  546. package/src/ui/screens/SearchSettingsScreen.tsx +9 -21
  547. package/src/ui/screens/UserLinksScreen.tsx +7 -14
  548. package/src/ui/screens/UserListScreen.tsx +2 -5
  549. package/src/ui/screens/WelcomeNewUserScreen.tsx +18 -48
  550. package/src/ui/screens/fileManagement/FileLibraryError.tsx +56 -0
  551. package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +56 -46
  552. package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +55 -71
  553. package/src/ui/screens/trust/TrustAboutScreen.tsx +10 -17
  554. package/src/ui/screens/trust/TrustCenterScreen.tsx +9 -28
  555. package/src/ui/screens/trust/TrustFAQScreen.tsx +15 -18
  556. package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +3 -5
  557. package/src/ui/screens/trust/TrustRewardsScreen.tsx +11 -26
  558. package/src/ui/screens/trust/TrustRulesScreen.tsx +10 -13
  559. package/src/ui/stores/resetSessionScopedStores.ts +8 -3
  560. package/src/ui/types/navigation.ts +10 -0
  561. package/src/ui/utils/avatarUtils.ts +11 -2
  562. package/src/ui/utils/fileManagement.ts +1 -101
  563. package/lib/commonjs/ui/components/Header.js +0 -305
  564. package/lib/commonjs/ui/components/Header.js.map +0 -1
  565. package/lib/commonjs/ui/components/OxyAccountDialog.js.map +0 -1
  566. package/lib/commonjs/ui/stores/fileStore.js +0 -153
  567. package/lib/commonjs/ui/stores/fileStore.js.map +0 -1
  568. package/lib/module/ui/components/Header.js +0 -299
  569. package/lib/module/ui/components/Header.js.map +0 -1
  570. package/lib/module/ui/components/OxyAccountDialog.js.map +0 -1
  571. package/lib/module/ui/stores/fileStore.js +0 -145
  572. package/lib/module/ui/stores/fileStore.js.map +0 -1
  573. package/lib/typescript/commonjs/ui/components/Header.d.ts +0 -33
  574. package/lib/typescript/commonjs/ui/components/Header.d.ts.map +0 -1
  575. package/lib/typescript/commonjs/ui/components/OxyAccountDialog.d.ts.map +0 -1
  576. package/lib/typescript/commonjs/ui/stores/fileStore.d.ts +0 -31
  577. package/lib/typescript/commonjs/ui/stores/fileStore.d.ts.map +0 -1
  578. package/lib/typescript/module/ui/components/Header.d.ts +0 -33
  579. package/lib/typescript/module/ui/components/Header.d.ts.map +0 -1
  580. package/lib/typescript/module/ui/components/OxyAccountDialog.d.ts.map +0 -1
  581. package/lib/typescript/module/ui/stores/fileStore.d.ts +0 -31
  582. package/lib/typescript/module/ui/stores/fileStore.d.ts.map +0 -1
  583. package/src/ui/components/Header.tsx +0 -224
  584. package/src/ui/stores/fileStore.ts +0 -118
@@ -8,10 +8,14 @@ var _react = require("react");
8
8
  var _reactNative = require("react-native");
9
9
  var _reactNativeGestureHandler = require("react-native-gesture-handler");
10
10
  var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
11
- var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
11
+ var _reactQuery = require("@tanstack/react-query");
12
12
  var _theme = require("@oxyhq/bloom/theme");
13
+ var _button = require("@oxyhq/bloom/button");
13
14
  var _core = require("@oxyhq/core");
15
+ var _OxyContext = require("../context/OxyContext.js");
14
16
  var _useI18n = require("../hooks/useI18n.js");
17
+ var _useReduceMotion = require("../hooks/useReduceMotion.js");
18
+ var _useSurfaceHeader = require("../hooks/useSurfaceHeader.js");
15
19
  var _bloom = require("@oxyhq/bloom");
16
20
  var _jsxRuntime = require("react/jsx-runtime");
17
21
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /**
@@ -21,11 +25,17 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
21
25
  * but before the avatar is uploaded. Inspired by iOS Photos, Google Photos and
22
26
  * Instagram crop tools.
23
27
  *
28
+ * Reached ONLY by navigating within a `ChangeAvatar` surface, so the panel
29
+ * morphs from the source list into the editor. The surface owns the chrome: this
30
+ * screen declares its title and its "Use photo" action through `useSurfaceHeader`
31
+ * and renders no bar of its own — the nav bar's back arrow is Cancel, and it
32
+ * returns to the source list.
33
+ *
24
34
  * Architecture:
25
- * - Full-bleed black canvas, independent of theme, so photos always read well.
26
- * - Translucent top bar with Cancel / Title / Done (primary CTA).
27
- * - Circular viewport with white ring, outer 50% black mask, and a 3x3
28
- * rule-of-thirds grid that appears during gestures and fades after 800ms.
35
+ * - A dark crop stage, independent of theme, so photos always read well, inset
36
+ * inside the surface's own themed panel.
37
+ * - Circular viewport with white ring and a 3x3 rule-of-thirds grid that
38
+ * appears during gestures and fades after 800ms.
29
39
  * - Floating zoom chip during pinch.
30
40
  * - Pan + pinch via Gesture Handler, transform driven by Reanimated.
31
41
  * - Reduced-motion aware entrance animation.
@@ -45,14 +55,20 @@ const VIEWPORT_SIZE = 320;
45
55
  const OUTPUT_SIZE = 512;
46
56
  const MIN_SCALE = 1;
47
57
  const MAX_SCALE = 4;
58
+ /** Zoom increment per +/- button press (web, where there is no pinch). */
59
+ const ZOOM_STEP = 0.5;
60
+ /** Tween duration for a button-driven zoom (collapses to 0 under reduce-motion). */
61
+ const ZOOM_BUTTON_DURATION_MS = 180;
48
62
  /** Duration (ms) that the rule-of-thirds grid lingers after a gesture ends. */
49
63
  const GRID_FADE_DELAY_MS = 800;
50
64
  const GRID_FADE_DURATION_MS = 220;
51
65
  /** Duration the zoom chip stays visible after a pinch ends. */
52
66
  const ZOOM_CHIP_FADE_DELAY_MS = 600;
53
67
  const ZOOM_CHIP_FADE_DURATION_MS = 200;
54
- /** Backdrop color is fixed independent of theme so the photo always reads well. */
68
+ /** Stage color is fixed independent of theme so the photo always reads well. */
55
69
  const CANVAS_BG = '#000000';
70
+ /** Corner radius of the dark stage block inside the surface's themed panel. */
71
+ const STAGE_RADIUS = 24;
56
72
  const RING_COLOR = '#ffffff';
57
73
  const RING_WIDTH = 2;
58
74
  const REMOTE_HTTP_URI_PATTERN = /^https?:\/\//i;
@@ -74,6 +90,26 @@ function clampTranslation(tx, ty, s, baseW, baseH) {
74
90
  ty: Math.min(Math.max(ty, -maxY), maxY)
75
91
  };
76
92
  }
93
+ /**
94
+ * Measure an image's intrinsic size via `Image.getSize`, wrapped as a Promise so
95
+ * it can be a React Query `queryFn` (no component state / effects). Rejects on a
96
+ * platform failure or degenerate dimensions so the query surfaces `isError`.
97
+ * Mirrors the `measurePhotoDimensions` helper the photo grid uses.
98
+ */
99
+ function measureImageSize(uri) {
100
+ return new Promise((resolve, reject) => {
101
+ _reactNative.Image.getSize(uri, (width, height) => {
102
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
103
+ reject(new Error('Image reported invalid dimensions'));
104
+ return;
105
+ }
106
+ resolve({
107
+ width,
108
+ height
109
+ });
110
+ }, () => reject(new Error('Image measurement failed')));
111
+ });
112
+ }
77
113
 
78
114
  /**
79
115
  * Lazy-loaded reference to the expo-image-manipulator module. The module is an
@@ -194,31 +230,86 @@ async function hapticSelection() {
194
230
  }
195
231
  }
196
232
  const AvatarCropScreen = ({
233
+ dismiss,
197
234
  goBack,
198
- onClose,
199
235
  imageUri,
236
+ imageFileId,
200
237
  sourceWidth,
201
- sourceHeight,
202
- onConfirm,
203
- onCancel
238
+ sourceHeight
204
239
  }) => {
205
240
  const theme = (0, _theme.useTheme)();
206
241
  const {
207
242
  t
208
243
  } = (0, _useI18n.useI18n)();
209
- const insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
210
-
211
- // Natural size of the source image. May be known up front (passed in) or
212
- // measured lazily via Image.getSize once the image loads.
213
- const [naturalSize, setNaturalSize] = (0, _react.useState)(sourceWidth && sourceHeight ? {
214
- width: sourceWidth,
215
- height: sourceHeight
216
- } : null);
244
+ const {
245
+ oxyServices
246
+ } = (0, _OxyContext.useOxy)();
247
+ // Reactive OS reduce-motion preference (useSyncExternalStore, no effect). Pins
248
+ // the entrance spring off. Declared before `entrance` so its initial rest value
249
+ // is correct under reduce-motion.
250
+ const reduceMotion = (0, _useReduceMotion.useReduceMotion)();
251
+
252
+ // The "My Oxy files" source hands us a file ID instead of a ready URL. Its
253
+ // download URL is usually private, so it must be resolved through the SDK
254
+ // (which throws on failure). Resolving it HERE — not in the source list — is
255
+ // what keeps the list from lingering on screen for the round-trip: this screen
256
+ // shows its own spinner on the dark canvas while the URL resolves. A React
257
+ // Query read (not an effect) so it stays declarative and cached.
258
+ const shouldResolveFile = !imageUri && !!imageFileId;
259
+ const sourceQuery = (0, _reactQuery.useQuery)({
260
+ queryKey: ['avatarCropSource', imageFileId],
261
+ enabled: shouldResolveFile,
262
+ staleTime: Number.POSITIVE_INFINITY,
263
+ retry: false,
264
+ queryFn: async () => {
265
+ if (!imageFileId) {
266
+ throw new Error('No file id to resolve for cropping');
267
+ }
268
+ const resolved = await oxyServices.assetGetUrl(imageFileId);
269
+ if (!resolved?.url) {
270
+ throw new Error('No download URL returned for the selected image');
271
+ }
272
+ return resolved.url;
273
+ }
274
+ });
275
+
276
+ // The URL the cropper actually loads: the passed `imageUri`, else the URL the
277
+ // file-ID query resolved. While it resolves, `effectiveUri` is undefined and
278
+ // the stage shows its own spinner (never the empty state).
279
+ const effectiveUri = imageUri ?? sourceQuery.data;
280
+ const isResolvingSource = shouldResolveFile && !sourceQuery.data && !sourceQuery.isError;
281
+ const sourceErrorMessage = sourceQuery.isError ? t('changeAvatar.errors.loadImageFailed') || 'Could not load the selected image' : null;
282
+
283
+ // Natural size of the source image. Known up front (device/camera sources pass
284
+ // the dimensions) OR measured lazily from `effectiveUri` via a React Query read
285
+ // (no effect) — the same Image.getSize→useQuery pattern the photo grid uses.
286
+ const hasPassedDimensions = !!(sourceWidth && sourceHeight);
287
+ const measureQuery = (0, _reactQuery.useQuery)({
288
+ queryKey: ['avatarCropMeasure', effectiveUri],
289
+ enabled: !!effectiveUri && !hasPassedDimensions,
290
+ queryFn: () => {
291
+ if (!effectiveUri) {
292
+ throw new Error('No image to measure');
293
+ }
294
+ return measureImageSize(effectiveUri);
295
+ },
296
+ staleTime: Number.POSITIVE_INFINITY,
297
+ retry: false,
298
+ placeholderData: _reactQuery.keepPreviousData
299
+ });
300
+ const naturalSize = (0, _react.useMemo)(() => {
301
+ if (sourceWidth && sourceHeight) return {
302
+ width: sourceWidth,
303
+ height: sourceHeight
304
+ };
305
+ return measureQuery.data ?? null;
306
+ }, [sourceWidth, sourceHeight, measureQuery.data]);
307
+ /** Measurement failed (bad dimensions / getSize error) — surfaced via the empty UI. */
308
+ const measureErrorMessage = measureQuery.isError ? t('editProfile.toasts.cropMeasureFailed') || 'Could not measure the image' : null;
217
309
  const [isProcessing, setIsProcessing] = (0, _react.useState)(false);
218
310
  const [zoomLabel, setZoomLabel] = (0, _react.useState)('1.0');
219
311
  /** True when scale != MIN_SCALE OR translate != 0 — used to reveal the reset link. */
220
312
  const [isModified, setIsModified] = (0, _react.useState)(false);
221
- const [reduceMotion, setReduceMotion] = (0, _react.useState)(false);
222
313
 
223
314
  // Shared values for the active gesture transform.
224
315
  const scale = (0, _reactNativeReanimated.useSharedValue)(MIN_SCALE);
@@ -268,99 +359,18 @@ const AvatarCropScreen = ({
268
359
  };
269
360
  }, [naturalSize]);
270
361
 
271
- // Track in-flight measurement to avoid duplicate Image.getSize calls when
272
- // the component re-renders before the previous getSize callback fires.
273
- const measuringUriRef = (0, _react.useRef)(null);
274
- /** Failure state for measurement, surfaced to the user via the empty UI. */
275
- const [measureError, setMeasureError] = (0, _react.useState)(null);
276
- const handleImageMeasured = (0, _react.useCallback)(uri => {
277
- if (measuringUriRef.current === uri) return;
278
- measuringUriRef.current = uri;
279
- // `logger.debug` is dev-gated upstream (no-op in production).
280
- // We deliberately don't log the full file URI in any production
281
- // path — only in debug builds — to avoid leaking on-device file
282
- // paths into logcat / Sentry breadcrumbs.
283
- _core.logger.debug('Measuring image', {
284
- component: LOG_COMPONENT
285
- });
286
- _reactNative.Image.getSize(uri, (w, h) => {
287
- _core.logger.debug('Image measured', {
288
- component: LOG_COMPONENT
289
- }, {
290
- width: w,
291
- height: h
292
- });
293
- if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) {
294
- const message = t('editProfile.toasts.cropMeasureFailed') || 'Could not measure the image';
295
- setMeasureError(message);
296
- _bloom.toast.error(message);
297
- measuringUriRef.current = null;
298
- return;
299
- }
300
- setMeasureError(null);
301
- setNaturalSize({
302
- width: w,
303
- height: h
304
- });
305
- }, () => {
306
- _core.logger.error('Image.getSize failed', new Error('Image measurement failed'), {
307
- component: LOG_COMPONENT
308
- });
309
- const message = t('editProfile.toasts.cropMeasureFailed') || 'Could not measure the image';
310
- setMeasureError(message);
311
- _bloom.toast.error(message);
312
- measuringUriRef.current = null;
313
- });
314
- }, [t]);
315
-
316
- // Kick off measurement once per imageUri. Using useEffect (not a render-body
317
- // side effect) so the call is scheduled exactly when the URI changes,
318
- // rather than being re-fired on every parent re-render.
319
- (0, _react.useEffect)(() => {
320
- if (!imageUri) return;
321
- if (sourceWidth && sourceHeight) return;
322
- if (naturalSize) return;
323
- handleImageMeasured(imageUri);
324
- }, [handleImageMeasured, imageUri, naturalSize, sourceHeight, sourceWidth]);
325
-
326
- // Dev-only one-time mount breadcrumb. `logger.debug` is dev-gated so
327
- // this is a no-op in production releases; we additionally avoid logging
328
- // the full `imageUri` to prevent leaking on-device file paths into any
329
- // breadcrumb sink that picks up debug output.
330
- (0, _react.useEffect)(() => {
331
- _core.logger.debug('mount', {
332
- component: LOG_COMPONENT
333
- }, {
334
- hasImageUri: !!imageUri,
335
- hasSourceDimensions: !!(sourceWidth && sourceHeight)
336
- });
337
- }, [imageUri, sourceHeight, sourceWidth]);
338
-
339
- // Detect reduce-motion preference once on mount + subscribe to changes.
340
- (0, _react.useEffect)(() => {
341
- let cancelled = false;
342
- _reactNative.AccessibilityInfo.isReduceMotionEnabled().then(enabled => {
343
- if (cancelled) return;
344
- setReduceMotion(enabled);
345
- if (enabled) {
346
- entrance.value = 1;
347
- }
348
- }).catch(() => {
349
- // Best-effort — fall back to motion enabled.
350
- });
351
- const sub = _reactNative.AccessibilityInfo.addEventListener('reduceMotionChanged', enabled => {
352
- setReduceMotion(enabled);
353
- if (enabled) entrance.value = 1;
354
- });
355
- return () => {
356
- cancelled = true;
357
- sub.remove();
358
- };
359
- }, [entrance]);
360
-
361
- // Play the entrance pulse exactly once when motion is allowed.
362
- (0, _react.useEffect)(() => {
363
- if (reduceMotion) return;
362
+ // Entrance pulse, driven from the crop frame's ref callback (fires on mount)
363
+ // rather than an effect the media-cleanup `startEntrance` pattern. Reduce
364
+ // motion pins the frame at rest; otherwise it springs in from 0.95→1. The
365
+ // callback depends on `reduceMotion`, so if that preference resolves/flips the
366
+ // callback re-runs with the node and re-pins (snap to 1) — matching the old
367
+ // effect that snapped the entrance to rest when reduce-motion turned on.
368
+ const startEntrance = (0, _react.useCallback)(node => {
369
+ if (!node) return; // unmount
370
+ if (reduceMotion) {
371
+ entrance.value = 1;
372
+ return;
373
+ }
364
374
  entrance.value = (0, _reactNativeReanimated.withSpring)(1, {
365
375
  damping: 14,
366
376
  stiffness: 180,
@@ -479,6 +489,11 @@ const AvatarCropScreen = ({
479
489
  (0, _reactNativeReanimated.runOnJS)(hideZoomChip)();
480
490
  }), [baseFit, commitTransform, hideGrid, hideZoomChip, logGestureStart, notifyMaxBoundHit, notifyMinBoundHit, resetPinchBounds, savedScale, scale, showGrid, showZoomChip, translateX, translateY, updateZoomLabel]);
481
491
  const composedGesture = (0, _react.useMemo)(() => _reactNativeGestureHandler.Gesture.Simultaneous(panGesture, pinchGesture), [panGesture, pinchGesture]);
492
+
493
+ // Deps list every shared value the mapper reads so it re-runs on web (RN-Web
494
+ // has no worklets plugin — a mapper omitting its driver SVs freezes at the
495
+ // first frame, which would leave the button-driven zoom stuck). Native
496
+ // auto-tracks and ignores the extra deps, so this is safe cross-platform.
482
497
  const imageAnimatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
483
498
  transform: [{
484
499
  translateX: translateX.value
@@ -487,12 +502,15 @@ const AvatarCropScreen = ({
487
502
  }, {
488
503
  scale: scale.value
489
504
  }]
490
- }));
505
+ }), [translateX, translateY, scale]);
506
+
507
+ // `[entrance]` in deps so the ref-callback-driven entrance spring ticks on
508
+ // RN-Web (no worklets plugin); native auto-tracks and ignores the extra dep.
491
509
  const cropFrameAnimatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
492
510
  transform: [{
493
511
  scale: entrance.value
494
512
  }]
495
- }));
513
+ }), [entrance]);
496
514
  const gridAnimatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
497
515
  opacity: gridOpacity.value
498
516
  }));
@@ -515,6 +533,43 @@ const AvatarCropScreen = ({
515
533
  _reactNative.AccessibilityInfo.announceForAccessibility(t('editProfile.crop.a11yResetAnnouncement') || 'Crop reset');
516
534
  }, [commitTransform, reduceMotion, scale, t, translateX, translateY]);
517
535
 
536
+ /**
537
+ * Web zoom controls. A desktop pointer has no pinch, so the +/- buttons drive
538
+ * the SAME `scale` shared value the pinch gesture does — clamped to the same
539
+ * bounds, with translation re-clamped through the shared {@link clampTranslation}
540
+ * helper so the image never leaves the viewport. Native keeps pinch (the
541
+ * buttons are hidden there). Reduced motion collapses the tween to an instant
542
+ * set. Reads the committed transform (refs) at press time, never during render.
543
+ */
544
+ const applyZoom = (0, _react.useCallback)(direction => {
545
+ if (!baseFit || isProcessing) return;
546
+ const current = committedScale.current;
547
+ const target = Math.min(MAX_SCALE, Math.max(MIN_SCALE, current + direction * ZOOM_STEP));
548
+ if (Math.abs(target - current) < 0.001) {
549
+ // Already at the bound — a soft selection tick, no transform change.
550
+ void hapticSelection();
551
+ return;
552
+ }
553
+ const clamped = clampTranslation(committedTranslateX.current, committedTranslateY.current, target, baseFit.width, baseFit.height);
554
+ const duration = reduceMotion ? 0 : ZOOM_BUTTON_DURATION_MS;
555
+ scale.value = (0, _reactNativeReanimated.withTiming)(target, {
556
+ duration
557
+ });
558
+ translateX.value = (0, _reactNativeReanimated.withTiming)(clamped.tx, {
559
+ duration
560
+ });
561
+ translateY.value = (0, _reactNativeReanimated.withTiming)(clamped.ty, {
562
+ duration
563
+ });
564
+ commitTransform(target, clamped.tx, clamped.ty);
565
+ void hapticImpact('light');
566
+ // Mirror the pinch's transient chrome so the buttons feel identical.
567
+ showGrid();
568
+ hideGrid();
569
+ showZoomChip();
570
+ hideZoomChip();
571
+ }, [baseFit, commitTransform, hideGrid, hideZoomChip, isProcessing, reduceMotion, scale, showGrid, showZoomChip, translateX, translateY]);
572
+
518
573
  /**
519
574
  * Convert the on-screen transform into pixel-space crop coordinates
520
575
  * relative to the source image, then invoke expo-image-manipulator to
@@ -532,7 +587,7 @@ const AvatarCropScreen = ({
532
587
  committedTranslateX: committedTranslateX.current,
533
588
  committedTranslateY: committedTranslateY.current
534
589
  });
535
- if (!imageUri || !baseFit || !naturalSize) {
590
+ if (!effectiveUri || !baseFit || !naturalSize) {
536
591
  _bloom.toast.error(t('editProfile.toasts.cropNotReady') || 'Image not ready yet');
537
592
  return;
538
593
  }
@@ -575,7 +630,7 @@ const AvatarCropScreen = ({
575
630
  cropSize,
576
631
  outputSize: OUTPUT_SIZE
577
632
  });
578
- const preparedImage = await prepareImageForManipulator(imageUri);
633
+ const preparedImage = await prepareImageForManipulator(effectiveUri);
579
634
  preparedImageCleanup = preparedImage.cleanup;
580
635
  const result = await manipulateAsync(preparedImage.uri, [{
581
636
  crop: {
@@ -602,16 +657,16 @@ const AvatarCropScreen = ({
602
657
  height: result.height
603
658
  });
604
659
  void hapticNotification('success');
605
- await onConfirm?.({
660
+
661
+ // Resolve the surface's present() promise with the cropped JPEG and
662
+ // close it. The awaiting caller (`useAvatarPicker`) handles the
663
+ // upload + any success toast.
664
+ dismiss?.({
606
665
  uri: result.uri,
607
666
  width: result.width,
608
667
  height: result.height,
609
668
  mime: 'image/jpeg'
610
669
  });
611
-
612
- // Close the sheet on success. The caller is responsible for any
613
- // success toast (uploads typically toast their own outcome).
614
- onClose?.();
615
670
  } catch (err) {
616
671
  const normalizedError = normalizeCropError(err);
617
672
  _core.logger.error('handleConfirm failed', normalizedError, {
@@ -623,86 +678,48 @@ const AvatarCropScreen = ({
623
678
  preparedImageCleanup?.();
624
679
  setIsProcessing(false);
625
680
  }
626
- }, [baseFit, imageUri, naturalSize, onClose, onConfirm, t]);
627
- const handleCancel = (0, _react.useCallback)(() => {
628
- onCancel?.();
629
- goBack?.();
630
- }, [goBack, onCancel]);
631
- const topInset = _reactNative.Platform.OS === 'ios' ? Math.max(insets.top, 12) : Math.max(insets.top, 16);
632
- const bottomInset = Math.max(insets.bottom, 16);
681
+ }, [baseFit, effectiveUri, naturalSize, dismiss, t]);
682
+
683
+ /**
684
+ * The surface's primary action, mounted into the Dialog nav bar's right slot
685
+ * (which is why it must stay referentially stable). While processing it keeps
686
+ * its width and shows a spinner; the a11y label carries the "Saving…" state
687
+ * the visible label can no longer show.
688
+ */
689
+ const doneAction = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
690
+ variant: "primary",
691
+ size: "small",
692
+ onPress: () => void handleConfirm(),
693
+ disabled: isProcessing || !baseFit,
694
+ loading: isProcessing,
695
+ accessibilityLabel: isProcessing ? t('editProfile.crop.saving') : t('editProfile.crop.confirm'),
696
+ children: t('editProfile.crop.confirm')
697
+ }), [baseFit, handleConfirm, isProcessing, t]);
698
+
699
+ // No bar of our own: the surface owns the chrome. `goBack` pops back to the
700
+ // ChangeAvatar source list (and dismisses the surface if this is somehow the
701
+ // root frame), which is exactly Cancel.
702
+ (0, _useSurfaceHeader.useSurfaceHeader)({
703
+ title: t('editProfile.crop.title'),
704
+ largeTitle: false,
705
+ right: doneAction,
706
+ onBack: goBack
707
+ });
633
708
  const styles = (0, _react.useMemo)(() => _reactNative.StyleSheet.create({
634
709
  container: {
635
- flex: 1,
636
- backgroundColor: CANVAS_BG
637
- },
638
- topBar: {
639
- paddingTop: topInset,
640
- paddingHorizontal: 12,
641
- paddingBottom: 10,
642
- flexDirection: 'row',
643
- alignItems: 'center',
644
- justifyContent: 'space-between',
645
- backgroundColor: 'rgba(0,0,0,0.6)',
646
- zIndex: 10
647
- },
648
- topBarTitleWrap: {
649
- flex: 1,
650
- alignItems: 'center',
651
- justifyContent: 'center',
652
- paddingHorizontal: 4
653
- },
654
- topBarTitle: {
655
- color: '#ffffff',
656
- fontSize: 17,
657
- letterSpacing: -0.2,
658
- ...(_reactNative.Platform.OS === 'web' ? {
659
- fontWeight: '600'
660
- } : null)
661
- },
662
- cancelBtn: {
663
- minWidth: 64,
664
- paddingHorizontal: 10,
665
- paddingVertical: 8,
666
- borderRadius: 18,
667
- alignItems: 'flex-start',
668
- justifyContent: 'center'
669
- },
670
- cancelLabel: {
671
- color: '#ffffff',
672
- fontSize: 15,
673
- opacity: 0.85
674
- },
675
- doneBtn: {
676
- minWidth: 76,
677
- paddingHorizontal: 14,
678
- paddingVertical: 8,
679
- borderRadius: 18,
680
- alignItems: 'center',
681
- justifyContent: 'center',
682
- backgroundColor: theme.colors.primary
683
- },
684
- doneBtnDisabled: {
685
- opacity: 0.5
686
- },
687
- doneLabel: {
688
- color: '#ffffff',
689
- fontSize: 15,
690
- letterSpacing: -0.1,
691
- ...(_reactNative.Platform.OS === 'web' ? {
692
- fontWeight: '600'
693
- } : null)
694
- },
695
- doneLabelLoading: {
696
- flexDirection: 'row',
697
- alignItems: 'center',
698
- justifyContent: 'center',
699
- gap: 8
710
+ backgroundColor: theme.colors.background
700
711
  },
701
712
  stage: {
702
- flex: 1,
713
+ backgroundColor: CANVAS_BG,
714
+ borderRadius: STAGE_RADIUS,
715
+ overflow: 'hidden',
716
+ // Top padding clears the zoom chip, which floats 44dp above
717
+ // the crop frame and would otherwise be clipped by `overflow`.
718
+ paddingTop: 60,
719
+ paddingBottom: 28,
720
+ paddingHorizontal: 16,
703
721
  alignItems: 'center',
704
- justifyContent: 'center',
705
- paddingHorizontal: 16
722
+ justifyContent: 'center'
706
723
  },
707
724
  cropFrame: {
708
725
  width: VIEWPORT_SIZE,
@@ -787,17 +804,14 @@ const AvatarCropScreen = ({
787
804
  letterSpacing: 0.2
788
805
  },
789
806
  helperBlock: {
790
- paddingHorizontal: 24,
791
- paddingTop: 24,
792
- paddingBottom: bottomInset,
807
+ paddingTop: 16,
793
808
  alignItems: 'center',
794
- justifyContent: 'flex-end',
795
- gap: 10
809
+ gap: 8
796
810
  },
797
811
  helper: {
798
812
  fontSize: 13,
799
813
  lineHeight: 18,
800
- color: 'rgba(255,255,255,0.6)',
814
+ color: theme.colors.textSecondary,
801
815
  textAlign: 'center',
802
816
  maxWidth: 320
803
817
  },
@@ -807,123 +821,72 @@ const AvatarCropScreen = ({
807
821
  },
808
822
  resetLinkText: {
809
823
  fontSize: 13,
810
- color: '#ffffff',
811
- opacity: 0.85,
824
+ color: theme.colors.primary,
812
825
  textDecorationLine: 'underline'
813
826
  },
814
827
  emptyState: {
815
- flex: 1,
816
828
  alignItems: 'center',
817
829
  justifyContent: 'center',
818
- padding: 24
830
+ paddingVertical: 48
819
831
  },
820
832
  emptyLabel: {
821
833
  fontSize: 14,
822
- color: 'rgba(255,255,255,0.7)',
834
+ color: theme.colors.textSecondary,
823
835
  textAlign: 'center'
824
836
  }
825
- }), [baseFit, bottomInset, theme, topInset]);
837
+ }), [baseFit, theme]);
826
838
 
827
839
  // Reset link reveal — only show when the image is not at the default
828
840
  // transform. Use derived display state to avoid mounting/unmounting jank.
829
841
  const resetLinkOpacity = isModified ? 1 : 0;
830
842
 
831
- // No image supplied OR measurement failed render a minimal empty state.
832
- if (!imageUri || measureError) {
833
- const emptyMessage = !imageUri ? t('editProfile.crop.noImage') || 'No image to crop' : measureError;
834
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
843
+ // Zoom-button state is derived from `zoomLabel` (reactive state, set on every
844
+ // commit) rather than the committed-scale ref, so it stays correct across
845
+ // renders without reading mutable state during render. The +/- pair is web-only
846
+ // (native has pinch).
847
+ const currentZoom = Number.parseFloat(zoomLabel) || MIN_SCALE;
848
+ const canZoomOut = currentZoom > MIN_SCALE + 0.001;
849
+ const canZoomIn = currentZoom < MAX_SCALE - 0.001;
850
+ const showZoomControls = _reactNative.Platform.OS === 'web';
851
+ const zoomOutDisabled = !canZoomOut || !baseFit || isProcessing;
852
+ const zoomInDisabled = !canZoomIn || !baseFit || isProcessing;
853
+
854
+ // No source at all (and none resolving), a resolution failure, or a
855
+ // measurement failure — render a minimal empty state. While a file ID is still
856
+ // resolving, fall THROUGH to the stage so its own spinner shows, not this.
857
+ // The surface's nav bar (back = cancel) is the only chrome needed here.
858
+ if (!effectiveUri && !isResolvingSource || sourceErrorMessage || measureErrorMessage) {
859
+ const emptyMessage = sourceErrorMessage ? sourceErrorMessage : measureErrorMessage ? measureErrorMessage : t('editProfile.crop.noImage');
860
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
835
861
  style: styles.container,
836
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
837
- style: styles.topBar,
838
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
839
- accessibilityLabel: t('editProfile.crop.cancel') || 'Cancel',
840
- accessibilityRole: "button",
841
- style: styles.cancelBtn,
842
- onPress: handleCancel,
843
- activeOpacity: 0.6,
844
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
845
- style: styles.cancelLabel,
846
- children: t('editProfile.crop.cancel') || 'Cancel'
847
- })
848
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
849
- style: styles.topBarTitleWrap,
850
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
851
- style: styles.topBarTitle,
852
- children: t('editProfile.crop.title') || 'Crop avatar'
853
- })
854
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
855
- style: styles.cancelBtn
856
- })]
857
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
862
+ className: "px-screen-margin pb-space-24",
863
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
858
864
  style: styles.emptyState,
859
865
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
860
866
  style: styles.emptyLabel,
861
867
  children: emptyMessage
862
868
  })
863
- })]
869
+ })
864
870
  });
865
871
  }
866
872
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
867
873
  style: styles.container,
874
+ className: "px-screen-margin pb-space-24",
868
875
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
869
- style: styles.topBar,
870
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
871
- accessibilityLabel: t('editProfile.crop.cancel') || 'Cancel',
872
- accessibilityRole: "button",
873
- style: styles.cancelBtn,
874
- onPress: handleCancel,
875
- disabled: isProcessing,
876
- activeOpacity: 0.6,
877
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
878
- style: styles.cancelLabel,
879
- children: t('editProfile.crop.cancel') || 'Cancel'
880
- })
881
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
882
- style: styles.topBarTitleWrap,
883
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
884
- style: styles.topBarTitle,
885
- numberOfLines: 1,
886
- children: t('editProfile.crop.title') || 'Crop avatar'
887
- })
888
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
889
- accessibilityLabel: t('editProfile.crop.confirm') || 'Use photo',
890
- accessibilityRole: "button",
891
- accessibilityState: {
892
- disabled: isProcessing || !baseFit,
893
- busy: isProcessing
894
- },
895
- style: [styles.doneBtn, (isProcessing || !baseFit) && styles.doneBtnDisabled],
896
- onPress: handleConfirm,
897
- disabled: isProcessing || !baseFit,
898
- activeOpacity: 0.85,
899
- children: isProcessing ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
900
- style: styles.doneLabelLoading,
901
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
902
- size: "small",
903
- color: "#ffffff"
904
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
905
- style: styles.doneLabel,
906
- children: t('editProfile.crop.saving') || 'Saving…'
907
- })]
908
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
909
- style: styles.doneLabel,
910
- children: t('editProfile.crop.confirm') || 'Use photo'
911
- })
912
- })]
913
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
914
876
  style: styles.stage,
915
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.View, {
877
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.View, {
878
+ ref: startEntrance,
916
879
  style: [styles.cropFrame, cropFrameAnimatedStyle],
917
880
  accessible: true,
918
881
  accessibilityRole: "image",
919
- accessibilityLabel: t('editProfile.crop.a11yImage') || 'Crop preview. Pinch to zoom and drag to reposition the image.',
882
+ accessibilityLabel: t('editProfile.crop.a11yImage'),
920
883
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
921
884
  gesture: composedGesture,
922
885
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
923
886
  style: styles.viewport,
924
- children: baseFit ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.Image, {
887
+ children: baseFit && effectiveUri ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.Image, {
925
888
  source: {
926
- uri: imageUri
889
+ uri: effectiveUri
927
890
  },
928
891
  style: [styles.image, imageAnimatedStyle],
929
892
  resizeMode: "cover"
@@ -961,17 +924,52 @@ const AvatarCropScreen = ({
961
924
  style: styles.zoomChipText,
962
925
  children: t('editProfile.crop.zoom', {
963
926
  value: zoomLabel
964
- }) || `${zoomLabel}×`
927
+ })
965
928
  })
966
929
  })]
967
- })
930
+ }), showZoomControls ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
931
+ className: "absolute bottom-4 left-0 right-0 items-center",
932
+ pointerEvents: "box-none",
933
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
934
+ className: "flex-row overflow-hidden rounded-full bg-black/70",
935
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
936
+ accessibilityRole: "button",
937
+ accessibilityLabel: t('editProfile.crop.zoomOut'),
938
+ accessibilityState: {
939
+ disabled: zoomOutDisabled
940
+ },
941
+ disabled: zoomOutDisabled,
942
+ onPress: () => applyZoom(-1),
943
+ className: `h-10 w-[52px] items-center justify-center active:bg-white/10${zoomOutDisabled ? ' opacity-40' : ''}`,
944
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
945
+ className: "text-white text-[22px] font-medium leading-[24px]",
946
+ children: '−'
947
+ })
948
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
949
+ className: "w-px self-stretch bg-white/25"
950
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
951
+ accessibilityRole: "button",
952
+ accessibilityLabel: t('editProfile.crop.zoomIn'),
953
+ accessibilityState: {
954
+ disabled: zoomInDisabled
955
+ },
956
+ disabled: zoomInDisabled,
957
+ onPress: () => applyZoom(1),
958
+ className: `h-10 w-[52px] items-center justify-center active:bg-white/10${zoomInDisabled ? ' opacity-40' : ''}`,
959
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
960
+ className: "text-white text-[22px] font-medium leading-[24px]",
961
+ children: '+'
962
+ })
963
+ })]
964
+ })
965
+ }) : null]
968
966
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
969
967
  style: styles.helperBlock,
970
968
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
971
969
  style: styles.helper,
972
- children: t('editProfile.crop.helper') || 'The cropped circle is what will appear on your profile. Pinch to zoom, drag to position.'
970
+ children: t('editProfile.crop.helper')
973
971
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
974
- accessibilityLabel: t('editProfile.crop.a11yReset') || 'Reset crop to default position',
972
+ accessibilityLabel: t('editProfile.crop.a11yReset'),
975
973
  accessibilityRole: "button",
976
974
  accessibilityState: {
977
975
  disabled: !isModified || isProcessing
@@ -983,7 +981,7 @@ const AvatarCropScreen = ({
983
981
  }],
984
982
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
985
983
  style: styles.resetLinkText,
986
- children: t('editProfile.crop.resetToCenter') || 'Reset to center'
984
+ children: t('editProfile.crop.resetToCenter')
987
985
  })
988
986
  })]
989
987
  })]