@oxyhq/services 25.0.1 → 26.0.1

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 (570) hide show
  1. package/README.md +2 -2
  2. package/android/src/main/java/so/oxy/identity/OxyIdentityStore.kt +127 -21
  3. package/expo-module.config.json +1 -4
  4. package/lib/commonjs/index.js +49 -18
  5. package/lib/commonjs/index.js.map +1 -1
  6. package/lib/commonjs/notifications/deviceNotifications.js +0 -63
  7. package/lib/commonjs/notifications/deviceNotifications.js.map +1 -1
  8. package/lib/commonjs/ui/boot/runProviderColdBoot.js +64 -20
  9. package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
  10. package/lib/commonjs/ui/components/FollowButton.js +4 -4
  11. package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
  12. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +1 -13
  13. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
  14. package/lib/commonjs/ui/components/OxyAuthChooser.js +8 -9
  15. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  16. package/lib/commonjs/ui/components/OxyProvider.js +7 -8
  17. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  18. package/lib/commonjs/ui/components/ProfileButton.js +1 -1
  19. package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
  20. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +30 -25
  21. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  22. package/lib/commonjs/ui/components/authChooser/primitives.js +9 -9
  23. package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
  24. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js +2 -2
  25. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js.map +1 -1
  26. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js +2 -2
  27. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
  28. package/lib/commonjs/ui/components/internal/PinInput.js +1 -3
  29. package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
  30. package/lib/commonjs/ui/components/logo/LogoText.js +4 -4
  31. package/lib/commonjs/ui/components/logo/LogoText.js.map +1 -1
  32. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js +2 -2
  33. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  34. package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js +2 -2
  35. package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js.map +1 -1
  36. package/lib/commonjs/ui/components/styles/shadow.js.map +1 -1
  37. package/lib/commonjs/ui/context/OxyContext.js +46 -32
  38. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  39. package/lib/commonjs/ui/context/commitSessionFlow.js +43 -3
  40. package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -1
  41. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +2 -15
  42. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  43. package/lib/commonjs/ui/context/useOxyAccountGraph.js +4 -3
  44. package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
  45. package/lib/commonjs/ui/hooks/mutations/mutationFactory.js +5 -5
  46. package/lib/commonjs/ui/hooks/mutations/mutationFactory.js.map +1 -1
  47. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +11 -11
  48. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  49. package/lib/commonjs/ui/hooks/mutations/useServicesMutations.js +9 -9
  50. package/lib/commonjs/ui/hooks/mutations/useServicesMutations.js.map +1 -1
  51. package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js +2 -3
  52. package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js.map +1 -1
  53. package/lib/commonjs/ui/hooks/queries/userCache.js +17 -17
  54. package/lib/commonjs/ui/hooks/queries/userCache.js.map +1 -1
  55. package/lib/commonjs/ui/hooks/useAssets.js.map +1 -1
  56. package/lib/commonjs/ui/hooks/useAsyncAction.js +7 -7
  57. package/lib/commonjs/ui/hooks/useAsyncAction.js.map +1 -1
  58. package/lib/commonjs/ui/hooks/useAuth.js +2 -4
  59. package/lib/commonjs/ui/hooks/useAuth.js.map +1 -1
  60. package/lib/commonjs/ui/hooks/useAvatarPicker.js +5 -5
  61. package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -1
  62. package/lib/commonjs/ui/hooks/useOnlineStatus.js +2 -3
  63. package/lib/commonjs/ui/hooks/useOnlineStatus.js.map +1 -1
  64. package/lib/commonjs/ui/hooks/useSessionManagement.js +2 -0
  65. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  66. package/lib/commonjs/ui/hooks/useSettingToggle.js +4 -4
  67. package/lib/commonjs/ui/hooks/useSettingToggle.js.map +1 -1
  68. package/lib/commonjs/ui/hooks/useSurfaceHeader.js +11 -68
  69. package/lib/commonjs/ui/hooks/useSurfaceHeader.js.map +1 -1
  70. package/lib/commonjs/ui/oauth/browserAuthTransport.js +64 -66
  71. package/lib/commonjs/ui/oauth/browserAuthTransport.js.map +1 -1
  72. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js +48 -0
  73. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js.map +1 -0
  74. package/lib/commonjs/ui/oauth/oauthPopup.js +0 -47
  75. package/lib/commonjs/ui/oauth/oauthPopup.js.map +1 -1
  76. package/lib/commonjs/ui/screens/AccountMembersScreen.js +10 -10
  77. package/lib/commonjs/ui/screens/AccountMembersScreen.js.map +1 -1
  78. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +8 -7
  79. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  80. package/lib/commonjs/ui/screens/AccountVerificationScreen.js +4 -4
  81. package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
  82. package/lib/commonjs/ui/screens/AppInfoScreen.js +9 -9
  83. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  84. package/lib/commonjs/ui/screens/AvatarCropScreen.js +3 -3
  85. package/lib/commonjs/ui/screens/AvatarCropScreen.js.map +1 -1
  86. package/lib/commonjs/ui/screens/ChangeAvatarScreen.js +7 -6
  87. package/lib/commonjs/ui/screens/ChangeAvatarScreen.js.map +1 -1
  88. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js +4 -4
  89. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js.map +1 -1
  90. package/lib/commonjs/ui/screens/CreateAccountScreen.js +3 -3
  91. package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
  92. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +3 -3
  93. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  94. package/lib/commonjs/ui/screens/EditProfileScreen.js +3 -2
  95. package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -1
  96. package/lib/commonjs/ui/screens/FAQScreen.js +2 -2
  97. package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
  98. package/lib/commonjs/ui/screens/FeedbackScreen.js +89 -90
  99. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  100. package/lib/commonjs/ui/screens/FileManagementScreen.js +20 -20
  101. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  102. package/lib/commonjs/ui/screens/FollowersListScreen.js.map +1 -1
  103. package/lib/commonjs/ui/screens/FollowingListScreen.js.map +1 -1
  104. package/lib/commonjs/ui/screens/HelpSupportScreen.js +7 -7
  105. package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
  106. package/lib/commonjs/ui/screens/HistoryViewScreen.js +34 -9
  107. package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
  108. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +3 -3
  109. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  110. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +3 -3
  111. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
  112. package/lib/commonjs/ui/screens/ManageAccountScreen.js +15 -15
  113. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  114. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +19 -19
  115. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  116. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +15 -15
  117. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  118. package/lib/commonjs/ui/screens/ProfileScreen.js +7 -17
  119. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  120. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +2 -2
  121. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
  122. package/lib/commonjs/ui/screens/UserListScreen.js +7 -13
  123. package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
  124. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +6 -5
  125. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  126. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +4 -1
  127. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  128. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js +24 -34
  129. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  130. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +1 -1
  131. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  132. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +4 -3
  133. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  134. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +1 -1
  135. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  136. package/lib/commonjs/ui/session/index.js +0 -7
  137. package/lib/commonjs/ui/session/index.js.map +1 -1
  138. package/lib/commonjs/ui/utils/crossOriginRestore.js +140 -0
  139. package/lib/commonjs/ui/utils/crossOriginRestore.js.map +1 -0
  140. package/lib/commonjs/ui/utils/fileManagement.js +24 -24
  141. package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
  142. package/lib/commonjs/ui/utils/oauthReturn.js +30 -19
  143. package/lib/commonjs/ui/utils/oauthReturn.js.map +1 -1
  144. package/lib/commonjs/ui/utils/userUtils.js +28 -27
  145. package/lib/commonjs/ui/utils/userUtils.js.map +1 -1
  146. package/lib/module/index.js +8 -20
  147. package/lib/module/index.js.map +1 -1
  148. package/lib/module/notifications/deviceNotifications.js +0 -62
  149. package/lib/module/notifications/deviceNotifications.js.map +1 -1
  150. package/lib/module/ui/boot/runProviderColdBoot.js +65 -21
  151. package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
  152. package/lib/module/ui/components/FollowButton.js +1 -1
  153. package/lib/module/ui/components/FollowButton.js.map +1 -1
  154. package/lib/module/ui/components/OxyAccountDialogScreen.js +1 -13
  155. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
  156. package/lib/module/ui/components/OxyAuthChooser.js +4 -5
  157. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  158. package/lib/module/ui/components/OxyProvider.js +6 -7
  159. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  160. package/lib/module/ui/components/ProfileButton.js +2 -2
  161. package/lib/module/ui/components/ProfileButton.js.map +1 -1
  162. package/lib/module/ui/components/authChooser/AccountsMenuView.js +8 -3
  163. package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  164. package/lib/module/ui/components/authChooser/primitives.js +1 -1
  165. package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
  166. package/lib/module/ui/components/authChooser/useUsernameAvailability.js +1 -1
  167. package/lib/module/ui/components/authChooser/useUsernameAvailability.js.map +1 -1
  168. package/lib/module/ui/components/fileManagement/UploadPreview.js +1 -1
  169. package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
  170. package/lib/module/ui/components/internal/PinInput.js +1 -3
  171. package/lib/module/ui/components/internal/PinInput.js.map +1 -1
  172. package/lib/module/ui/components/logo/LogoText.js +4 -4
  173. package/lib/module/ui/components/logo/LogoText.js.map +1 -1
  174. package/lib/module/ui/components/payment/PaymentDetailsStep.js +1 -1
  175. package/lib/module/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  176. package/lib/module/ui/components/payment/PaymentSummaryStep.js +2 -2
  177. package/lib/module/ui/components/payment/PaymentSummaryStep.js.map +1 -1
  178. package/lib/module/ui/components/styles/shadow.js.map +1 -1
  179. package/lib/module/ui/context/OxyContext.js +49 -35
  180. package/lib/module/ui/context/OxyContext.js.map +1 -1
  181. package/lib/module/ui/context/commitSessionFlow.js +42 -3
  182. package/lib/module/ui/context/commitSessionFlow.js.map +1 -1
  183. package/lib/module/ui/context/hooks/useAuthOperations.js +2 -15
  184. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  185. package/lib/module/ui/context/useOxyAccountGraph.js +4 -3
  186. package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
  187. package/lib/module/ui/hooks/mutations/mutationFactory.js +1 -1
  188. package/lib/module/ui/hooks/mutations/mutationFactory.js.map +1 -1
  189. package/lib/module/ui/hooks/mutations/useAccountMutations.js +1 -1
  190. package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  191. package/lib/module/ui/hooks/mutations/useServicesMutations.js +1 -1
  192. package/lib/module/ui/hooks/mutations/useServicesMutations.js.map +1 -1
  193. package/lib/module/ui/hooks/queries/usePaymentQueries.js +2 -3
  194. package/lib/module/ui/hooks/queries/usePaymentQueries.js.map +1 -1
  195. package/lib/module/ui/hooks/queries/userCache.js +17 -17
  196. package/lib/module/ui/hooks/queries/userCache.js.map +1 -1
  197. package/lib/module/ui/hooks/useAssets.js.map +1 -1
  198. package/lib/module/ui/hooks/useAsyncAction.js +1 -1
  199. package/lib/module/ui/hooks/useAsyncAction.js.map +1 -1
  200. package/lib/module/ui/hooks/useAuth.js +2 -4
  201. package/lib/module/ui/hooks/useAuth.js.map +1 -1
  202. package/lib/module/ui/hooks/useAvatarPicker.js +1 -1
  203. package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -1
  204. package/lib/module/ui/hooks/useOnlineStatus.js +2 -3
  205. package/lib/module/ui/hooks/useOnlineStatus.js.map +1 -1
  206. package/lib/module/ui/hooks/useSessionManagement.js +2 -0
  207. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  208. package/lib/module/ui/hooks/useSettingToggle.js +1 -1
  209. package/lib/module/ui/hooks/useSettingToggle.js.map +1 -1
  210. package/lib/module/ui/hooks/useSurfaceHeader.js +11 -68
  211. package/lib/module/ui/hooks/useSurfaceHeader.js.map +1 -1
  212. package/lib/module/ui/oauth/browserAuthTransport.js +64 -66
  213. package/lib/module/ui/oauth/browserAuthTransport.js.map +1 -1
  214. package/lib/module/ui/oauth/legacyRedirectLanes.js +44 -0
  215. package/lib/module/ui/oauth/legacyRedirectLanes.js.map +1 -0
  216. package/lib/module/ui/oauth/oauthPopup.js +1 -48
  217. package/lib/module/ui/oauth/oauthPopup.js.map +1 -1
  218. package/lib/module/ui/screens/AccountMembersScreen.js +1 -1
  219. package/lib/module/ui/screens/AccountMembersScreen.js.map +1 -1
  220. package/lib/module/ui/screens/AccountSettingsScreen.js +4 -3
  221. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  222. package/lib/module/ui/screens/AccountVerificationScreen.js +1 -1
  223. package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
  224. package/lib/module/ui/screens/AppInfoScreen.js +1 -1
  225. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  226. package/lib/module/ui/screens/AvatarCropScreen.js +1 -1
  227. package/lib/module/ui/screens/AvatarCropScreen.js.map +1 -1
  228. package/lib/module/ui/screens/ChangeAvatarScreen.js +5 -4
  229. package/lib/module/ui/screens/ChangeAvatarScreen.js.map +1 -1
  230. package/lib/module/ui/screens/ConnectedAppsScreen.js +2 -2
  231. package/lib/module/ui/screens/ConnectedAppsScreen.js.map +1 -1
  232. package/lib/module/ui/screens/CreateAccountScreen.js +1 -1
  233. package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
  234. package/lib/module/ui/screens/EditProfileFieldScreen.js +1 -1
  235. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  236. package/lib/module/ui/screens/EditProfileScreen.js +4 -3
  237. package/lib/module/ui/screens/EditProfileScreen.js.map +1 -1
  238. package/lib/module/ui/screens/FAQScreen.js +1 -1
  239. package/lib/module/ui/screens/FAQScreen.js.map +1 -1
  240. package/lib/module/ui/screens/FeedbackScreen.js +91 -94
  241. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  242. package/lib/module/ui/screens/FileManagementScreen.js +1 -1
  243. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  244. package/lib/module/ui/screens/FollowersListScreen.js.map +1 -1
  245. package/lib/module/ui/screens/FollowingListScreen.js.map +1 -1
  246. package/lib/module/ui/screens/HelpSupportScreen.js +1 -1
  247. package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
  248. package/lib/module/ui/screens/HistoryViewScreen.js +30 -5
  249. package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
  250. package/lib/module/ui/screens/LanguageSelectorScreen.js +1 -1
  251. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  252. package/lib/module/ui/screens/LegalDocumentsScreen.js +1 -1
  253. package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
  254. package/lib/module/ui/screens/ManageAccountScreen.js +3 -3
  255. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  256. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +4 -4
  257. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  258. package/lib/module/ui/screens/PrivacySettingsScreen.js +11 -11
  259. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  260. package/lib/module/ui/screens/ProfileScreen.js +8 -18
  261. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  262. package/lib/module/ui/screens/SavesCollectionsScreen.js +1 -1
  263. package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
  264. package/lib/module/ui/screens/UserListScreen.js +8 -14
  265. package/lib/module/ui/screens/UserListScreen.js.map +1 -1
  266. package/lib/module/ui/screens/WelcomeNewUserScreen.js +6 -5
  267. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  268. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +4 -1
  269. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  270. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js +5 -15
  271. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  272. package/lib/module/ui/screens/trust/TrustCenterScreen.js +1 -1
  273. package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  274. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +5 -4
  275. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  276. package/lib/module/ui/screens/trust/TrustRewardsScreen.js +1 -1
  277. package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  278. package/lib/module/ui/session/index.js +0 -1
  279. package/lib/module/ui/session/index.js.map +1 -1
  280. package/lib/module/ui/utils/crossOriginRestore.js +131 -0
  281. package/lib/module/ui/utils/crossOriginRestore.js.map +1 -0
  282. package/lib/module/ui/utils/fileManagement.js +25 -25
  283. package/lib/module/ui/utils/fileManagement.js.map +1 -1
  284. package/lib/module/ui/utils/oauthReturn.js +30 -20
  285. package/lib/module/ui/utils/oauthReturn.js.map +1 -1
  286. package/lib/module/ui/utils/userUtils.js +28 -27
  287. package/lib/module/ui/utils/userUtils.js.map +1 -1
  288. package/lib/typescript/commonjs/index.d.ts +2 -0
  289. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  290. package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts +0 -51
  291. package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts.map +1 -1
  292. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts +30 -11
  293. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  294. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  295. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts +0 -7
  296. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  297. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  298. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
  299. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  300. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +1 -1
  301. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
  302. package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts +1 -1
  303. package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
  304. package/lib/typescript/commonjs/ui/components/internal/PinInput.d.ts.map +1 -1
  305. package/lib/typescript/commonjs/ui/components/payment/types.d.ts +6 -6
  306. package/lib/typescript/commonjs/ui/components/payment/types.d.ts.map +1 -1
  307. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  308. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts +40 -0
  309. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts.map +1 -1
  310. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +2 -11
  311. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  312. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +7 -26
  313. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  314. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +1 -0
  315. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  316. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  317. package/lib/typescript/commonjs/ui/hooks/queries/paymentTypes.d.ts +2 -3
  318. package/lib/typescript/commonjs/ui/hooks/queries/paymentTypes.d.ts.map +1 -1
  319. package/lib/typescript/commonjs/ui/hooks/queries/usePaymentQueries.d.ts +2 -3
  320. package/lib/typescript/commonjs/ui/hooks/queries/usePaymentQueries.d.ts.map +1 -1
  321. package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts +2 -2
  322. package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts.map +1 -1
  323. package/lib/typescript/commonjs/ui/hooks/useAssets.d.ts +1 -1
  324. package/lib/typescript/commonjs/ui/hooks/useAssets.d.ts.map +1 -1
  325. package/lib/typescript/commonjs/ui/hooks/useAsyncAction.d.ts +2 -2
  326. package/lib/typescript/commonjs/ui/hooks/useAsyncAction.d.ts.map +1 -1
  327. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts +2 -4
  328. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -1
  329. package/lib/typescript/commonjs/ui/hooks/useOnlineStatus.d.ts +2 -3
  330. package/lib/typescript/commonjs/ui/hooks/useOnlineStatus.d.ts.map +1 -1
  331. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
  332. package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts +2 -7
  333. package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts.map +1 -1
  334. package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts.map +1 -1
  335. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts +40 -0
  336. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts.map +1 -0
  337. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts +0 -6
  338. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts.map +1 -1
  339. package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
  340. package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -1
  341. package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts +2 -2
  342. package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
  343. package/lib/typescript/commonjs/ui/screens/FollowersListScreen.d.ts +0 -3
  344. package/lib/typescript/commonjs/ui/screens/FollowersListScreen.d.ts.map +1 -1
  345. package/lib/typescript/commonjs/ui/screens/FollowingListScreen.d.ts +0 -3
  346. package/lib/typescript/commonjs/ui/screens/FollowingListScreen.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/ManageAccountScreen.d.ts.map +1 -1
  349. package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  350. package/lib/typescript/commonjs/ui/screens/ProfileScreen.d.ts.map +1 -1
  351. package/lib/typescript/commonjs/ui/screens/UserListScreen.d.ts +0 -7
  352. package/lib/typescript/commonjs/ui/screens/UserListScreen.d.ts.map +1 -1
  353. package/lib/typescript/commonjs/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  354. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  355. package/lib/typescript/commonjs/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  356. package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts +1 -1
  357. package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts.map +1 -1
  358. package/lib/typescript/commonjs/ui/session/index.d.ts +0 -1
  359. package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
  360. package/lib/typescript/commonjs/ui/types/navigation.d.ts +19 -27
  361. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  362. package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts +43 -0
  363. package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts.map +1 -0
  364. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +5 -5
  365. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
  366. package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts +12 -15
  367. package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts.map +1 -1
  368. package/lib/typescript/commonjs/ui/utils/userUtils.d.ts +14 -7
  369. package/lib/typescript/commonjs/ui/utils/userUtils.d.ts.map +1 -1
  370. package/lib/typescript/module/index.d.ts +2 -0
  371. package/lib/typescript/module/index.d.ts.map +1 -1
  372. package/lib/typescript/module/notifications/deviceNotifications.d.ts +0 -51
  373. package/lib/typescript/module/notifications/deviceNotifications.d.ts.map +1 -1
  374. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts +30 -11
  375. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  376. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  377. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts +0 -7
  378. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  379. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  380. package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
  381. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  382. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +1 -1
  383. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
  384. package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts +1 -1
  385. package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
  386. package/lib/typescript/module/ui/components/internal/PinInput.d.ts.map +1 -1
  387. package/lib/typescript/module/ui/components/payment/types.d.ts +6 -6
  388. package/lib/typescript/module/ui/components/payment/types.d.ts.map +1 -1
  389. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  390. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts +40 -0
  391. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts.map +1 -1
  392. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +2 -11
  393. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  394. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +7 -26
  395. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  396. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +1 -0
  397. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  398. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  399. package/lib/typescript/module/ui/hooks/queries/paymentTypes.d.ts +2 -3
  400. package/lib/typescript/module/ui/hooks/queries/paymentTypes.d.ts.map +1 -1
  401. package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts +2 -3
  402. package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts.map +1 -1
  403. package/lib/typescript/module/ui/hooks/queries/userCache.d.ts +2 -2
  404. package/lib/typescript/module/ui/hooks/queries/userCache.d.ts.map +1 -1
  405. package/lib/typescript/module/ui/hooks/useAssets.d.ts +1 -1
  406. package/lib/typescript/module/ui/hooks/useAssets.d.ts.map +1 -1
  407. package/lib/typescript/module/ui/hooks/useAsyncAction.d.ts +2 -2
  408. package/lib/typescript/module/ui/hooks/useAsyncAction.d.ts.map +1 -1
  409. package/lib/typescript/module/ui/hooks/useAuth.d.ts +2 -4
  410. package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
  411. package/lib/typescript/module/ui/hooks/useOnlineStatus.d.ts +2 -3
  412. package/lib/typescript/module/ui/hooks/useOnlineStatus.d.ts.map +1 -1
  413. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
  414. package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts +2 -7
  415. package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts.map +1 -1
  416. package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts.map +1 -1
  417. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts +40 -0
  418. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts.map +1 -0
  419. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts +0 -6
  420. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts.map +1 -1
  421. package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
  422. package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -1
  423. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts +2 -2
  424. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
  425. package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts +0 -3
  426. package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts.map +1 -1
  427. package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts +0 -3
  428. package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts.map +1 -1
  429. package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
  430. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  431. package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  432. package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
  433. package/lib/typescript/module/ui/screens/UserListScreen.d.ts +0 -7
  434. package/lib/typescript/module/ui/screens/UserListScreen.d.ts.map +1 -1
  435. package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  436. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  437. package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  438. package/lib/typescript/module/ui/screens/trust/trustTier.d.ts +1 -1
  439. package/lib/typescript/module/ui/screens/trust/trustTier.d.ts.map +1 -1
  440. package/lib/typescript/module/ui/session/index.d.ts +0 -1
  441. package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
  442. package/lib/typescript/module/ui/types/navigation.d.ts +19 -27
  443. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  444. package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts +43 -0
  445. package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts.map +1 -0
  446. package/lib/typescript/module/ui/utils/fileManagement.d.ts +5 -5
  447. package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
  448. package/lib/typescript/module/ui/utils/oauthReturn.d.ts +12 -15
  449. package/lib/typescript/module/ui/utils/oauthReturn.d.ts.map +1 -1
  450. package/lib/typescript/module/ui/utils/userUtils.d.ts +14 -7
  451. package/lib/typescript/module/ui/utils/userUtils.d.ts.map +1 -1
  452. package/package.json +10 -22
  453. package/src/index.ts +16 -18
  454. package/src/notifications/deviceNotifications.ts +0 -82
  455. package/src/ui/boot/__tests__/coldBootWebAuthMode.test.ts +281 -0
  456. package/src/ui/boot/runProviderColdBoot.ts +101 -24
  457. package/src/ui/components/FollowButton.tsx +1 -1
  458. package/src/ui/components/OxyAccountDialogScreen.tsx +1 -13
  459. package/src/ui/components/OxyAuthChooser.tsx +4 -14
  460. package/src/ui/components/OxyProvider.tsx +7 -8
  461. package/src/ui/components/ProfileButton.tsx +2 -5
  462. package/src/ui/components/authChooser/AccountsMenuView.tsx +10 -5
  463. package/src/ui/components/authChooser/primitives.tsx +1 -1
  464. package/src/ui/components/authChooser/useUsernameAvailability.ts +1 -1
  465. package/src/ui/components/fileManagement/UploadPreview.tsx +1 -1
  466. package/src/ui/components/internal/PinInput.tsx +0 -1
  467. package/src/ui/components/logo/LogoText.tsx +4 -4
  468. package/src/ui/components/payment/PaymentDetailsStep.tsx +1 -1
  469. package/src/ui/components/payment/PaymentSummaryStep.tsx +2 -2
  470. package/src/ui/components/payment/types.ts +24 -24
  471. package/src/ui/components/styles/shadow.tsx +2 -2
  472. package/src/ui/context/OxyContext.tsx +46 -35
  473. package/src/ui/context/__tests__/commitSessionFlow.test.ts +89 -13
  474. package/src/ui/context/commitSessionFlow.ts +61 -3
  475. package/src/ui/context/hooks/useAuthOperations.ts +1 -26
  476. package/src/ui/context/oxyContextTypes.ts +7 -26
  477. package/src/ui/context/useOxyAccountGraph.ts +4 -4
  478. package/src/ui/hooks/mutations/mutationFactory.ts +1 -1
  479. package/src/ui/hooks/mutations/useAccountMutations.ts +1 -1
  480. package/src/ui/hooks/mutations/useServicesMutations.ts +1 -1
  481. package/src/ui/hooks/queries/paymentTypes.ts +2 -3
  482. package/src/ui/hooks/queries/usePaymentQueries.ts +2 -3
  483. package/src/ui/hooks/queries/userCache.ts +148 -169
  484. package/src/ui/hooks/useAssets.ts +1 -1
  485. package/src/ui/hooks/useAsyncAction.ts +3 -3
  486. package/src/ui/hooks/useAuth.ts +2 -4
  487. package/src/ui/hooks/useAvatarPicker.ts +1 -1
  488. package/src/ui/hooks/useOnlineStatus.ts +2 -3
  489. package/src/ui/hooks/useSessionManagement.ts +2 -0
  490. package/src/ui/hooks/useSettingToggle.ts +1 -1
  491. package/src/ui/hooks/useSurfaceHeader.ts +15 -90
  492. package/src/ui/oauth/__tests__/oauthPopup.test.ts +0 -26
  493. package/src/ui/oauth/browserAuthTransport.ts +49 -55
  494. package/src/ui/oauth/legacyRedirectLanes.ts +43 -0
  495. package/src/ui/oauth/oauthPopup.ts +3 -61
  496. package/src/ui/screens/AccountMembersScreen.tsx +1 -1
  497. package/src/ui/screens/AccountSettingsScreen.tsx +5 -5
  498. package/src/ui/screens/AccountVerificationScreen.tsx +1 -1
  499. package/src/ui/screens/AppInfoScreen.tsx +1 -1
  500. package/src/ui/screens/AvatarCropScreen.tsx +1 -1
  501. package/src/ui/screens/ChangeAvatarScreen.tsx +4 -7
  502. package/src/ui/screens/ConnectedAppsScreen.tsx +2 -2
  503. package/src/ui/screens/CreateAccountScreen.tsx +1 -1
  504. package/src/ui/screens/EditProfileFieldScreen.tsx +1 -1
  505. package/src/ui/screens/EditProfileScreen.tsx +3 -6
  506. package/src/ui/screens/FAQScreen.tsx +1 -1
  507. package/src/ui/screens/FeedbackScreen.tsx +575 -741
  508. package/src/ui/screens/FileManagementScreen.tsx +1 -1
  509. package/src/ui/screens/FollowersListScreen.tsx +0 -3
  510. package/src/ui/screens/FollowingListScreen.tsx +0 -3
  511. package/src/ui/screens/HelpSupportScreen.tsx +1 -1
  512. package/src/ui/screens/HistoryViewScreen.tsx +20 -5
  513. package/src/ui/screens/LanguageSelectorScreen.tsx +1 -1
  514. package/src/ui/screens/LegalDocumentsScreen.tsx +1 -1
  515. package/src/ui/screens/ManageAccountScreen.tsx +2 -9
  516. package/src/ui/screens/PremiumSubscriptionScreen.tsx +4 -4
  517. package/src/ui/screens/PrivacySettingsScreen.tsx +12 -15
  518. package/src/ui/screens/ProfileScreen.tsx +6 -24
  519. package/src/ui/screens/SavesCollectionsScreen.tsx +1 -1
  520. package/src/ui/screens/UserListScreen.tsx +8 -18
  521. package/src/ui/screens/WelcomeNewUserScreen.tsx +6 -6
  522. package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +1 -1
  523. package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +5 -14
  524. package/src/ui/screens/trust/TrustCenterScreen.tsx +2 -2
  525. package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +5 -6
  526. package/src/ui/screens/trust/TrustRewardsScreen.tsx +1 -1
  527. package/src/ui/screens/trust/TrustRulesScreen.tsx +1 -1
  528. package/src/ui/screens/trust/trustTier.ts +1 -1
  529. package/src/ui/session/index.ts +0 -1
  530. package/src/ui/types/navigation.ts +19 -27
  531. package/src/ui/utils/__tests__/crossOriginRestore.test.ts +143 -0
  532. package/src/ui/utils/crossOriginRestore.ts +169 -0
  533. package/src/ui/utils/fileManagement.ts +92 -108
  534. package/src/ui/utils/oauthReturn.ts +33 -23
  535. package/src/ui/utils/userUtils.ts +32 -27
  536. package/android/src/main/java/so/oxy/session/OxyBackgroundSession.kt +0 -184
  537. package/android/src/main/java/so/oxy/session/OxyBackgroundSessionApi.kt +0 -162
  538. package/android/src/main/java/so/oxy/session/OxyBackgroundSessionModule.kt +0 -116
  539. package/android/src/main/java/so/oxy/session/OxyBackgroundSessionStore.kt +0 -179
  540. package/android/src/main/java/so/oxy/session/OxyBackgroundToken.kt +0 -61
  541. package/android/src/main/java/so/oxy/storage/OxyEncryptedPrefs.kt +0 -241
  542. package/lib/commonjs/ui/session/backgroundSession.js +0 -258
  543. package/lib/commonjs/ui/session/backgroundSession.js.map +0 -1
  544. package/lib/commonjs/ui/session/useBackgroundSessionSync.js +0 -81
  545. package/lib/commonjs/ui/session/useBackgroundSessionSync.js.map +0 -1
  546. package/lib/commonjs/ui/utils/netConnectivity.js +0 -28
  547. package/lib/commonjs/ui/utils/netConnectivity.js.map +0 -1
  548. package/lib/module/ui/session/backgroundSession.js +0 -252
  549. package/lib/module/ui/session/backgroundSession.js.map +0 -1
  550. package/lib/module/ui/session/useBackgroundSessionSync.js +0 -76
  551. package/lib/module/ui/session/useBackgroundSessionSync.js.map +0 -1
  552. package/lib/module/ui/utils/netConnectivity.js +0 -23
  553. package/lib/module/ui/utils/netConnectivity.js.map +0 -1
  554. package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts +0 -42
  555. package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts.map +0 -1
  556. package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts +0 -23
  557. package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts.map +0 -1
  558. package/lib/typescript/commonjs/ui/utils/netConnectivity.d.ts +0 -17
  559. package/lib/typescript/commonjs/ui/utils/netConnectivity.d.ts.map +0 -1
  560. package/lib/typescript/module/ui/session/backgroundSession.d.ts +0 -42
  561. package/lib/typescript/module/ui/session/backgroundSession.d.ts.map +0 -1
  562. package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts +0 -23
  563. package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts.map +0 -1
  564. package/lib/typescript/module/ui/utils/netConnectivity.d.ts +0 -17
  565. package/lib/typescript/module/ui/utils/netConnectivity.d.ts.map +0 -1
  566. package/src/ui/boot/__tests__/coldBootNoIdpRedirect.test.ts +0 -215
  567. package/src/ui/session/__tests__/backgroundSession.test.ts +0 -392
  568. package/src/ui/session/backgroundSession.ts +0 -313
  569. package/src/ui/session/useBackgroundSessionSync.ts +0 -92
  570. package/src/ui/utils/netConnectivity.ts +0 -27
@@ -1,33 +1,31 @@
1
- import Ionicons from "@expo/vector-icons/Ionicons";
2
- import type MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
3
- import { Button } from "@oxyhq/bloom/button";
1
+ import type React from 'react';
2
+ import { useState, useRef, useCallback, useMemo } from 'react';
4
3
  import {
5
- SettingsListGroup,
6
- SettingsListItem,
7
- } from "@oxyhq/bloom/settings-list";
8
- import { Switch } from "@oxyhq/bloom/switch";
9
- import { TextField, TextFieldInput } from "@oxyhq/bloom/text-field";
10
- import { useTheme } from "@oxyhq/bloom/theme";
11
- import { toast } from "@oxyhq/bloom/toast";
12
- import { H2, Text } from "@oxyhq/bloom/typography";
13
- import { normalizeTheme } from "@oxyhq/core";
14
- import { packageInfo } from "@oxyhq/core";
15
- import type React from "react";
16
- import { useCallback, useMemo, useRef, useState } from "react";
17
- import { Animated, Platform, StyleSheet, View } from "react-native";
18
- import { SettingsIcon } from "../components/SettingsIcon";
19
- import { useOxy } from "../context/OxyContext";
20
- import { useI18n } from "../hooks/useI18n";
21
- import { useSurfaceHeader } from "../hooks/useSurfaceHeader";
22
- import type { BaseScreenProps } from "../types/navigation";
23
-
24
- import {
25
- CATEGORIES,
26
- FEEDBACK_TYPES,
27
- PRIORITY_LEVELS,
28
- } from "../components/feedback/constants";
29
- import type { FeedbackData } from "../components/feedback/types";
30
- import { useFeedbackForm } from "../components/feedback/useFeedbackForm";
4
+ View,
5
+ Platform,
6
+ Animated,
7
+ StyleSheet,
8
+ } from 'react-native';
9
+ import type { BaseScreenProps } from '../types/navigation';
10
+ import { normalizeTheme } from '@oxyhq/core';
11
+ import { packageInfo } from '@oxyhq/core';
12
+ import { useTheme } from '@oxyhq/bloom/theme';
13
+ import Ionicons from '@expo/vector-icons/Ionicons';
14
+ import type MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
15
+ import { toast } from '@oxyhq/bloom';
16
+ import { H2, Text } from '@oxyhq/bloom/typography';
17
+ import { Button } from '@oxyhq/bloom/button';
18
+ import { TextField, TextFieldInput } from '@oxyhq/bloom/text-field';
19
+ import { Switch } from '@oxyhq/bloom/switch';
20
+ import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
21
+ import { SettingsIcon } from '../components/SettingsIcon';
22
+ import { useI18n } from '../hooks/useI18n';
23
+ import { useSurfaceHeader } from '../hooks/useSurfaceHeader';
24
+ import { useOxy } from '../context/OxyContext';
25
+
26
+ import { useFeedbackForm } from '../components/feedback/useFeedbackForm';
27
+ import { FEEDBACK_TYPES, PRIORITY_LEVELS, CATEGORIES } from '../components/feedback/constants';
28
+ import type { FeedbackData } from '../components/feedback/types';
31
29
 
32
30
  /** Step transition timing — measured animation, not a design token. */
33
31
  const STEP_FADE_OUT_MS = 250;
@@ -39,728 +37,564 @@ const LAST_STEP_INDEX = TOTAL_STEPS - 1;
39
37
  const SUCCESS_RESET_DELAY_MS = 3000;
40
38
 
41
39
  /** Maps each feedback type to a Bloom theme role + MaterialCommunityIcons glyph. */
42
- const TYPE_ICON_GLYPH: Record<
43
- FeedbackData["type"],
44
- React.ComponentProps<typeof MaterialCommunityIcons>["name"]
45
- > = {
46
- bug: "bug",
47
- feature: "lightbulb-on",
48
- general: "chat",
49
- support: "help-circle",
40
+ const TYPE_ICON_GLYPH: Record<FeedbackData['type'], React.ComponentProps<typeof MaterialCommunityIcons>['name']> = {
41
+ bug: 'bug',
42
+ feature: 'lightbulb-on',
43
+ general: 'chat',
44
+ support: 'help-circle',
50
45
  };
51
46
 
52
47
  /** Maps each priority level to a MaterialCommunityIcons glyph. */
53
- const PRIORITY_ICON_GLYPH: Record<
54
- FeedbackData["priority"],
55
- React.ComponentProps<typeof MaterialCommunityIcons>["name"]
56
- > = {
57
- low: "arrow-down",
58
- medium: "minus",
59
- high: "arrow-up",
60
- critical: "alert",
48
+ const PRIORITY_ICON_GLYPH: Record<FeedbackData['priority'], React.ComponentProps<typeof MaterialCommunityIcons>['name']> = {
49
+ low: 'arrow-down',
50
+ medium: 'minus',
51
+ high: 'arrow-up',
52
+ critical: 'alert',
61
53
  };
62
54
 
63
55
  const FeedbackScreen: React.FC<BaseScreenProps> = ({
64
- goBack,
65
- onClose,
66
- theme,
56
+ goBack,
57
+ onClose,
58
+ theme,
67
59
  }) => {
68
- const { user, oxyServices } = useOxy();
69
- const normalizedTheme = normalizeTheme(theme);
70
- const bloomTheme = useTheme();
71
- const colors = bloomTheme.colors;
72
- const { t } = useI18n();
73
-
74
- useSurfaceHeader({ title: t("feedback.title") || "Feedback" });
75
-
76
- const {
77
- feedbackData,
78
- feedbackState,
79
- setFeedbackState,
80
- updateField,
81
- resetForm,
82
- } = useFeedbackForm();
83
-
84
- const [currentStep, setCurrentStep] = useState(0);
85
- const [, setErrorMessage] = useState("");
86
-
87
- const fadeAnim = useRef(new Animated.Value(1)).current;
88
- const slideAnim = useRef(new Animated.Value(0)).current;
89
-
90
- /** Theme-role color for each feedback type pill. */
91
- const typeColor = useCallback(
92
- (id: FeedbackData["type"]): string => {
93
- switch (id) {
94
- case "bug":
95
- return colors.negative;
96
- case "feature":
97
- return colors.info;
98
- case "general":
99
- return colors.success;
100
- case "support":
101
- return colors.warning;
102
- default:
103
- return colors.primary;
104
- }
105
- },
106
- [colors],
107
- );
108
-
109
- /** Theme-role color for each priority level. */
110
- const priorityColor = useCallback(
111
- (id: FeedbackData["priority"]): string => {
112
- switch (id) {
113
- case "low":
114
- return colors.success;
115
- case "medium":
116
- return colors.warning;
117
- case "high":
118
- return colors.negative;
119
- case "critical":
120
- return colors.negative;
121
- default:
122
- return colors.primary;
123
- }
124
- },
125
- [colors],
126
- );
127
-
128
- const animateTransition = useCallback(
129
- (nextStep: number) => {
130
- Animated.timing(fadeAnim, {
131
- toValue: 0,
132
- duration: STEP_FADE_OUT_MS,
133
- useNativeDriver: Platform.OS !== "web",
134
- }).start(() => {
135
- setCurrentStep(nextStep);
136
- slideAnim.setValue(STEP_SLIDE_FROM);
137
-
138
- Animated.parallel([
139
- Animated.timing(fadeAnim, {
140
- toValue: 1,
141
- duration: STEP_FADE_IN_MS,
142
- useNativeDriver: Platform.OS !== "web",
143
- }),
144
- Animated.timing(slideAnim, {
145
- toValue: 0,
146
- duration: STEP_SLIDE_IN_MS,
147
- useNativeDriver: Platform.OS !== "web",
148
- }),
149
- ]).start();
150
- });
151
- },
152
- [fadeAnim, slideAnim],
153
- );
154
-
155
- const nextStep = useCallback(() => {
156
- if (currentStep < LAST_STEP_INDEX) {
157
- animateTransition(currentStep + 1);
158
- }
159
- }, [currentStep, animateTransition]);
160
-
161
- const prevStep = useCallback(() => {
162
- if (currentStep > 0) {
163
- animateTransition(currentStep - 1);
164
- }
165
- }, [currentStep, animateTransition]);
166
-
167
- const isTypeStepValid = useCallback(() => {
168
- return Boolean(feedbackData.type && feedbackData.category);
169
- }, [feedbackData.type, feedbackData.category]);
170
-
171
- const isDetailsStepValid = useCallback(() => {
172
- return Boolean(
173
- feedbackData.title.trim() && feedbackData.description.trim(),
174
- );
175
- }, [feedbackData.title, feedbackData.description]);
176
-
177
- const isContactStepValid = useCallback(() => {
178
- return Boolean(feedbackData.contactEmail.trim() || user?.email);
179
- }, [feedbackData.contactEmail, user?.email]);
180
-
181
- const handleSubmitFeedback = useCallback(async () => {
182
- if (!isTypeStepValid() || !isDetailsStepValid() || !isContactStepValid()) {
183
- toast.error(
184
- t("feedback.toasts.fillRequired") ||
185
- "Please fill in all required fields",
186
- );
187
- return;
188
- }
189
-
190
- try {
191
- setFeedbackState({ status: "submitting", message: "" });
192
- setErrorMessage("");
193
-
194
- const feedbackPayload = {
195
- type: feedbackData.type,
196
- title: feedbackData.title,
197
- description: feedbackData.description,
198
- priority: feedbackData.priority,
199
- category: feedbackData.category,
200
- contactEmail: feedbackData.contactEmail || user?.email,
201
- systemInfo: feedbackData.systemInfo
202
- ? {
203
- platform: Platform.OS,
204
- version: Platform.Version?.toString() || "Unknown",
205
- appVersion: packageInfo.version,
206
- userId: user?.id,
207
- username: user?.username,
208
- timestamp: new Date().toISOString(),
209
- }
210
- : undefined,
211
- };
212
-
213
- await oxyServices.submitFeedback(feedbackPayload);
214
-
215
- setFeedbackState({
216
- status: "success",
217
- message:
218
- t("feedback.toasts.submitSuccess") ||
219
- "Feedback submitted successfully!",
220
- });
221
- toast.success(
222
- t("feedback.toasts.thanks") || "Thank you for your feedback!",
223
- );
224
-
225
- setTimeout(() => {
226
- resetForm();
227
- setCurrentStep(0);
228
- }, SUCCESS_RESET_DELAY_MS);
229
- } catch (error: unknown) {
230
- const message =
231
- (error instanceof Error ? error.message : null) ||
232
- t("feedback.toasts.submitFailed") ||
233
- "Failed to submit feedback";
234
- setFeedbackState({ status: "error", message });
235
- toast.error(message);
236
- }
237
- }, [
238
- feedbackData,
239
- user,
240
- oxyServices,
241
- isTypeStepValid,
242
- isDetailsStepValid,
243
- isContactStepValid,
244
- resetForm,
245
- setFeedbackState,
246
- t,
247
- ]);
248
-
249
- const feedbackTypeData = useMemo(
250
- () =>
251
- FEEDBACK_TYPES.map((type) => ({
252
- ...type,
253
- isSelected: feedbackData.type === type.id,
254
- })),
255
- [feedbackData.type],
256
- );
257
-
258
- const categoryData = useMemo(
259
- () =>
260
- feedbackData.type
261
- ? (CATEGORIES[feedbackData.type] || []).map((cat) => ({
262
- name: cat,
263
- isSelected: feedbackData.category === cat,
264
- }))
265
- : [],
266
- [feedbackData.type, feedbackData.category],
267
- );
268
-
269
- const priorityData = useMemo(
270
- () =>
271
- PRIORITY_LEVELS.map((p) => ({
272
- ...p,
273
- isSelected: feedbackData.priority === p.id,
274
- })),
275
- [feedbackData.priority],
276
- );
277
-
278
- const renderProgress = () => (
279
- <View
280
- className="flex-row justify-center gap-space-8 pt-space-8 pb-space-16"
281
- accessibilityRole="progressbar"
282
- accessibilityLabel={`Step ${currentStep + 1} of ${TOTAL_STEPS}`}
283
- >
284
- {Array.from({ length: TOTAL_STEPS }, (_, index) => (
285
- <View
286
- // biome-ignore lint/suspicious/noArrayIndexKey: fixed step indicators, order never changes
287
- key={index}
288
- className={
289
- currentStep === index
290
- ? "h-space-8 rounded-radius-max bg-fill-brand"
291
- : "h-space-8 rounded-radius-max bg-fill-secondary"
292
- }
293
- style={
294
- currentStep === index
295
- ? styles.progressDotActive
296
- : styles.progressDot
297
- }
298
- />
299
- ))}
300
- </View>
301
- );
302
-
303
- const renderStepHeader = (title: string, subtitle: string) => (
304
- <View className="w-full gap-space-8 mb-space-24">
305
- <H2 className="text-headerBold font-headerBold text-text">{title}</H2>
306
- <Text className="text-body font-body text-text-secondary">
307
- {subtitle}
308
- </Text>
309
- </View>
310
- );
311
-
312
- const renderTypeStep = () => (
313
- <Animated.View
314
- style={[
315
- styles.stepContainer,
316
- { opacity: fadeAnim, transform: [{ translateX: slideAnim }] },
317
- ]}
318
- >
319
- {renderStepHeader(
320
- t("feedback.type.title") || "What type of feedback?",
321
- t("feedback.type.subtitle") ||
322
- "Choose the category that best describes your feedback",
323
- )}
324
-
325
- <View className="w-full">
326
- <SettingsListGroup>
327
- {feedbackTypeData.map((type) => (
328
- <SettingsListItem
329
- key={type.id}
330
- icon={
331
- <SettingsIcon
332
- name={TYPE_ICON_GLYPH[type.id]}
333
- color={typeColor(type.id)}
334
- />
335
- }
336
- title={type.label}
337
- description={type.description}
338
- onPress={() => {
339
- updateField("type", type.id);
340
- updateField("category", "");
341
- }}
342
- showChevron={false}
343
- />
344
- ))}
345
- </SettingsListGroup>
346
- </View>
347
-
348
- {feedbackData.type ? (
349
- <View className="w-full mt-space-24">
350
- <Text className="text-caption font-caption text-text-secondary mb-space-8">
351
- {t("feedback.category.label") || "Category"}
352
- </Text>
353
- <View className="w-full">
354
- <SettingsListGroup>
355
- {categoryData.map((cat) => (
356
- <SettingsListItem
357
- key={cat.name}
358
- icon={
359
- <SettingsIcon
360
- name={cat.isSelected ? "check-circle" : "circle-outline"}
361
- color={
362
- cat.isSelected ? colors.primary : colors.textSecondary
363
- }
364
- />
365
- }
366
- title={cat.name}
367
- onPress={() => updateField("category", cat.name)}
368
- showChevron={false}
369
- />
370
- ))}
371
- </SettingsListGroup>
372
- </View>
373
- </View>
374
- ) : null}
375
-
376
- <View className="flex-row gap-space-8 mt-space-24 w-full">
377
- <Button
378
- variant="secondary"
379
- onPress={goBack}
380
- accessibilityLabel="Go back"
381
- icon={<Ionicons name="arrow-back" size={16} color={colors.text} />}
382
- style={styles.navButton}
383
- >
384
- {t("common.actions.back") || "Back"}
385
- </Button>
386
-
387
- <Button
388
- variant="primary"
389
- onPress={nextStep}
390
- disabled={!isTypeStepValid()}
391
- accessibilityLabel="Continue to next step"
392
- iconPosition="right"
393
- icon={
394
- <Ionicons
395
- name="arrow-forward"
396
- size={16}
397
- color={colors.primaryForeground}
398
- />
399
- }
400
- style={styles.navButton}
401
- >
402
- {t("common.actions.next") || "Next"}
403
- </Button>
404
- </View>
405
- </Animated.View>
406
- );
407
-
408
- const renderDetailsStep = () => (
409
- <Animated.View
410
- style={[
411
- styles.stepContainer,
412
- { opacity: fadeAnim, transform: [{ translateX: slideAnim }] },
413
- ]}
414
- >
415
- {renderStepHeader(
416
- t("feedback.details.title") || "Tell us more",
417
- t("feedback.details.subtitle") || "Provide details about your feedback",
418
- )}
419
-
420
- <View className="w-full gap-space-16">
421
- <TextField>
422
- <TextFieldInput
423
- floatingLabel
424
- label={t("feedback.fields.title.label") || "Title"}
425
- value={feedbackData.title}
426
- onChangeText={(text) => {
427
- updateField("title", text);
428
- setErrorMessage("");
429
- }}
430
- placeholder={
431
- t("feedback.fields.title.placeholder") ||
432
- "Brief summary of your feedback"
433
- }
434
- testID="feedback-title-input"
435
- accessibilityLabel="Feedback title"
436
- accessibilityHint="Enter a brief summary of your feedback"
437
- />
438
- </TextField>
439
-
440
- <TextField>
441
- <TextFieldInput
442
- floatingLabel
443
- multiline
444
- numberOfLines={6}
445
- label={t("feedback.fields.description.label") || "Description"}
446
- value={feedbackData.description}
447
- onChangeText={(text) => {
448
- updateField("description", text);
449
- setErrorMessage("");
450
- }}
451
- placeholder={
452
- t("feedback.fields.description.placeholder") ||
453
- "Please provide detailed information..."
454
- }
455
- testID="feedback-description-input"
456
- accessibilityLabel="Feedback description"
457
- accessibilityHint="Provide detailed information about your feedback"
458
- />
459
- </TextField>
460
- </View>
461
-
462
- <View className="w-full mt-space-24">
463
- <Text className="text-caption font-caption text-text-secondary mb-space-8">
464
- {t("feedback.priority.label") || "Priority Level"}
465
- </Text>
466
- <View className="w-full">
467
- <SettingsListGroup>
468
- {priorityData.map((p) => (
469
- <SettingsListItem
470
- key={p.id}
471
- icon={
472
- <SettingsIcon
473
- name={PRIORITY_ICON_GLYPH[p.id]}
474
- color={priorityColor(p.id)}
475
- />
476
- }
477
- title={p.label}
478
- onPress={() => updateField("priority", p.id)}
479
- showChevron={false}
480
- />
481
- ))}
482
- </SettingsListGroup>
483
- </View>
484
- </View>
485
-
486
- <View className="flex-row gap-space-8 mt-space-24 w-full">
487
- <Button
488
- variant="secondary"
489
- onPress={prevStep}
490
- accessibilityLabel="Go back"
491
- icon={<Ionicons name="arrow-back" size={16} color={colors.text} />}
492
- style={styles.navButton}
493
- >
494
- {t("common.actions.back") || "Back"}
495
- </Button>
496
-
497
- <Button
498
- variant="primary"
499
- onPress={nextStep}
500
- disabled={!isDetailsStepValid()}
501
- accessibilityLabel="Continue to next step"
502
- iconPosition="right"
503
- icon={
504
- <Ionicons
505
- name="arrow-forward"
506
- size={16}
507
- color={colors.primaryForeground}
508
- />
509
- }
510
- style={styles.navButton}
511
- >
512
- {t("common.actions.next") || "Next"}
513
- </Button>
514
- </View>
515
- </Animated.View>
516
- );
517
-
518
- const renderContactStep = () => (
519
- <Animated.View
520
- style={[
521
- styles.stepContainer,
522
- { opacity: fadeAnim, transform: [{ translateX: slideAnim }] },
523
- ]}
524
- >
525
- {renderStepHeader(
526
- t("feedback.contact.title") || "Contact Information",
527
- t("feedback.contact.subtitle") || "Help us get back to you",
528
- )}
529
-
530
- <View className="w-full">
531
- <TextField>
532
- <TextFieldInput
533
- floatingLabel
534
- label={t("feedback.fields.email.label") || "Email Address"}
535
- value={feedbackData.contactEmail}
536
- onChangeText={(text) => {
537
- updateField("contactEmail", text);
538
- setErrorMessage("");
539
- }}
540
- placeholder={
541
- user?.email ||
542
- t("feedback.fields.email.placeholder") ||
543
- "Enter your email address"
544
- }
545
- keyboardType="email-address"
546
- autoCapitalize="none"
547
- autoCorrect={false}
548
- testID="feedback-email-input"
549
- accessibilityLabel="Email address"
550
- accessibilityHint="Enter your email so we can respond"
551
- />
552
- </TextField>
553
- </View>
554
-
555
- <View className="w-full mt-space-16">
556
- <SettingsListGroup>
557
- <SettingsListItem
558
- icon={<SettingsIcon name="information" color={colors.info} />}
559
- title={
560
- t("feedback.contact.includeSystemInfo") ||
561
- "Include system information to help us better understand your issue"
562
- }
563
- rightElement={
564
- <Switch
565
- value={feedbackData.systemInfo}
566
- onValueChange={(value) => updateField("systemInfo", value)}
567
- testID="feedback-system-info-switch"
568
- />
569
- }
570
- showChevron={false}
571
- />
572
- </SettingsListGroup>
573
- </View>
574
-
575
- <View className="flex-row gap-space-8 mt-space-24 w-full">
576
- <Button
577
- variant="secondary"
578
- onPress={prevStep}
579
- accessibilityLabel="Go back"
580
- icon={<Ionicons name="arrow-back" size={16} color={colors.text} />}
581
- style={styles.navButton}
582
- >
583
- {t("common.actions.back") || "Back"}
584
- </Button>
585
-
586
- <Button
587
- variant="primary"
588
- onPress={nextStep}
589
- disabled={!isContactStepValid()}
590
- accessibilityLabel="Continue to summary"
591
- iconPosition="right"
592
- icon={
593
- <Ionicons
594
- name="arrow-forward"
595
- size={16}
596
- color={colors.primaryForeground}
597
- />
598
- }
599
- style={styles.navButton}
600
- >
601
- {t("common.actions.next") || "Next"}
602
- </Button>
603
- </View>
604
- </Animated.View>
605
- );
606
-
607
- const renderSummaryRow = (label: string, value: string | undefined) => (
608
- <View className="flex-row gap-space-12">
609
- <Text
610
- className="text-body font-body text-text-secondary"
611
- style={styles.summaryLabel}
612
- >
613
- {label}
614
- </Text>
615
- <Text className="text-body font-body text-text flex-1">{value}</Text>
616
- </View>
617
- );
618
-
619
- const renderSummaryStep = () => (
620
- <Animated.View
621
- style={[
622
- styles.stepContainer,
623
- { opacity: fadeAnim, transform: [{ translateX: slideAnim }] },
624
- ]}
625
- >
626
- {renderStepHeader(
627
- t("feedback.summary.title") || "Summary",
628
- t("feedback.summary.subtitle") ||
629
- "Please review your feedback before submitting",
630
- )}
631
-
632
- <View className="w-full gap-space-12 p-space-16 rounded-radius-20 bg-fill mb-space-24">
633
- {renderSummaryRow(
634
- t("feedback.summary.type") || "Type:",
635
- FEEDBACK_TYPES.find((ft) => ft.id === feedbackData.type)?.label,
636
- )}
637
- {renderSummaryRow(
638
- t("feedback.summary.category") || "Category:",
639
- feedbackData.category,
640
- )}
641
- {renderSummaryRow(
642
- t("feedback.summary.priority") || "Priority:",
643
- PRIORITY_LEVELS.find((p) => p.id === feedbackData.priority)?.label,
644
- )}
645
- {renderSummaryRow(
646
- t("feedback.summary.titleField") || "Title:",
647
- feedbackData.title,
648
- )}
649
- {renderSummaryRow(
650
- t("feedback.summary.contact") || "Contact:",
651
- feedbackData.contactEmail || user?.email,
652
- )}
653
- </View>
654
-
655
- <Button
656
- variant="primary"
657
- onPress={handleSubmitFeedback}
658
- disabled={feedbackState.status === "submitting"}
659
- loading={feedbackState.status === "submitting"}
660
- testID="submit-feedback-button"
661
- accessibilityLabel="Submit feedback"
662
- iconPosition="right"
663
- icon={
664
- <Ionicons name="send" size={18} color={colors.primaryForeground} />
665
- }
666
- style={styles.fullWidthButton}
667
- >
668
- {t("feedback.actions.submit") || "Submit Feedback"}
669
- </Button>
670
-
671
- <View className="flex-row mt-space-16 w-full">
672
- <Button
673
- variant="secondary"
674
- onPress={prevStep}
675
- accessibilityLabel="Go back"
676
- icon={<Ionicons name="arrow-back" size={16} color={colors.text} />}
677
- style={styles.navButton}
678
- >
679
- {t("common.actions.back") || "Back"}
680
- </Button>
681
- </View>
682
- </Animated.View>
683
- );
684
-
685
- const renderSuccessStep = () => (
686
- <Animated.View
687
- style={[
688
- styles.stepContainer,
689
- { opacity: fadeAnim, transform: [{ translateX: slideAnim }] },
690
- ]}
691
- >
692
- <View className="w-full items-center justify-center p-space-32 gap-space-16">
693
- <View className="p-space-24 rounded-radius-max bg-fill-secondary">
694
- <Ionicons name="checkmark-circle" size={48} color={colors.success} />
695
- </View>
696
- <H2 className="text-headerBold font-headerBold text-text text-center">
697
- {t("feedback.success.thanks") || "Thank You!"}
698
- </H2>
699
- <Text className="text-body font-body text-text-secondary text-center">
700
- {t("feedback.success.message") ||
701
- "Your feedback has been submitted successfully. We'll review it and get back to you soon."}
702
- </Text>
703
- <Button
704
- variant="primary"
705
- onPress={() => {
706
- resetForm();
707
- setCurrentStep(0);
708
- }}
709
- accessibilityLabel="Submit another feedback"
710
- style={styles.fullWidthButton}
711
- >
712
- {t("feedback.actions.submitAnother") || "Submit Another"}
713
- </Button>
714
- </View>
715
- </Animated.View>
716
- );
717
-
718
- const renderCurrentStep = () => {
719
- if (feedbackState.status === "success") return renderSuccessStep();
720
- switch (currentStep) {
721
- case 0:
722
- return renderTypeStep();
723
- case 1:
724
- return renderDetailsStep();
725
- case 2:
726
- return renderContactStep();
727
- case 3:
728
- return renderSummaryStep();
729
- default:
730
- return renderTypeStep();
731
- }
732
- };
733
-
734
- return (
735
- <>
736
- <View className="px-screen-margin pt-space-24 pb-space-32">
737
- {feedbackState.status !== "success" ? renderProgress() : null}
738
- {renderCurrentStep()}
739
- </View>
740
- </>
741
- );
60
+ const { user, oxyServices } = useOxy();
61
+ const normalizedTheme = normalizeTheme(theme);
62
+ const bloomTheme = useTheme();
63
+ const colors = bloomTheme.colors;
64
+ const { t } = useI18n();
65
+
66
+ useSurfaceHeader({ title: t('feedback.title') || 'Feedback' });
67
+
68
+ const { feedbackData, feedbackState, setFeedbackState, updateField, resetForm } = useFeedbackForm();
69
+
70
+ const [currentStep, setCurrentStep] = useState(0);
71
+ const [, setErrorMessage] = useState('');
72
+
73
+ const fadeAnim = useRef(new Animated.Value(1)).current;
74
+ const slideAnim = useRef(new Animated.Value(0)).current;
75
+
76
+ /** Theme-role color for each feedback type pill. */
77
+ const typeColor = useCallback((id: FeedbackData['type']): string => {
78
+ switch (id) {
79
+ case 'bug':
80
+ return colors.negative;
81
+ case 'feature':
82
+ return colors.info;
83
+ case 'general':
84
+ return colors.success;
85
+ case 'support':
86
+ return colors.warning;
87
+ default:
88
+ return colors.primary;
89
+ }
90
+ }, [colors]);
91
+
92
+ /** Theme-role color for each priority level. */
93
+ const priorityColor = useCallback((id: FeedbackData['priority']): string => {
94
+ switch (id) {
95
+ case 'low':
96
+ return colors.success;
97
+ case 'medium':
98
+ return colors.warning;
99
+ case 'high':
100
+ return colors.negative;
101
+ case 'critical':
102
+ return colors.negative;
103
+ default:
104
+ return colors.primary;
105
+ }
106
+ }, [colors]);
107
+
108
+ const animateTransition = useCallback((nextStep: number) => {
109
+ Animated.timing(fadeAnim, {
110
+ toValue: 0,
111
+ duration: STEP_FADE_OUT_MS,
112
+ useNativeDriver: Platform.OS !== 'web',
113
+ }).start(() => {
114
+ setCurrentStep(nextStep);
115
+ slideAnim.setValue(STEP_SLIDE_FROM);
116
+
117
+ Animated.parallel([
118
+ Animated.timing(fadeAnim, {
119
+ toValue: 1,
120
+ duration: STEP_FADE_IN_MS,
121
+ useNativeDriver: Platform.OS !== 'web',
122
+ }),
123
+ Animated.timing(slideAnim, {
124
+ toValue: 0,
125
+ duration: STEP_SLIDE_IN_MS,
126
+ useNativeDriver: Platform.OS !== 'web',
127
+ }),
128
+ ]).start();
129
+ });
130
+ }, [fadeAnim, slideAnim]);
131
+
132
+ const nextStep = useCallback(() => {
133
+ if (currentStep < LAST_STEP_INDEX) {
134
+ animateTransition(currentStep + 1);
135
+ }
136
+ }, [currentStep, animateTransition]);
137
+
138
+ const prevStep = useCallback(() => {
139
+ if (currentStep > 0) {
140
+ animateTransition(currentStep - 1);
141
+ }
142
+ }, [currentStep, animateTransition]);
143
+
144
+ const isTypeStepValid = useCallback(() => {
145
+ return Boolean(feedbackData.type && feedbackData.category);
146
+ }, [feedbackData.type, feedbackData.category]);
147
+
148
+ const isDetailsStepValid = useCallback(() => {
149
+ return Boolean(feedbackData.title.trim() && feedbackData.description.trim());
150
+ }, [feedbackData.title, feedbackData.description]);
151
+
152
+ const isContactStepValid = useCallback(() => {
153
+ return Boolean(feedbackData.contactEmail.trim() || user?.email);
154
+ }, [feedbackData.contactEmail, user?.email]);
155
+
156
+ const handleSubmitFeedback = useCallback(async () => {
157
+ if (!isTypeStepValid() || !isDetailsStepValid() || !isContactStepValid()) {
158
+ toast.error(t('feedback.toasts.fillRequired') || 'Please fill in all required fields');
159
+ return;
160
+ }
161
+
162
+ try {
163
+ setFeedbackState({ status: 'submitting', message: '' });
164
+ setErrorMessage('');
165
+
166
+ const feedbackPayload = {
167
+ type: feedbackData.type,
168
+ title: feedbackData.title,
169
+ description: feedbackData.description,
170
+ priority: feedbackData.priority,
171
+ category: feedbackData.category,
172
+ contactEmail: feedbackData.contactEmail || user?.email,
173
+ systemInfo: feedbackData.systemInfo ? {
174
+ platform: Platform.OS,
175
+ version: Platform.Version?.toString() || 'Unknown',
176
+ appVersion: packageInfo.version,
177
+ userId: user?.id,
178
+ username: user?.username,
179
+ timestamp: new Date().toISOString(),
180
+ } : undefined,
181
+ };
182
+
183
+ await oxyServices.submitFeedback(feedbackPayload);
184
+
185
+ setFeedbackState({ status: 'success', message: t('feedback.toasts.submitSuccess') || 'Feedback submitted successfully!' });
186
+ toast.success(t('feedback.toasts.thanks') || 'Thank you for your feedback!');
187
+
188
+ setTimeout(() => {
189
+ resetForm();
190
+ setCurrentStep(0);
191
+ }, SUCCESS_RESET_DELAY_MS);
192
+
193
+ } catch (error: unknown) {
194
+ const message = (error instanceof Error ? error.message : null)
195
+ || (t('feedback.toasts.submitFailed') || 'Failed to submit feedback');
196
+ setFeedbackState({ status: 'error', message });
197
+ toast.error(message);
198
+ }
199
+ }, [feedbackData, user, oxyServices, isTypeStepValid, isDetailsStepValid, isContactStepValid, resetForm, setFeedbackState, t]);
200
+
201
+ const feedbackTypeData = useMemo(() => FEEDBACK_TYPES.map(type => ({
202
+ ...type,
203
+ isSelected: feedbackData.type === type.id,
204
+ })), [feedbackData.type]);
205
+
206
+ const categoryData = useMemo(() => (feedbackData.type ? (CATEGORIES[feedbackData.type] || []).map(cat => ({
207
+ name: cat,
208
+ isSelected: feedbackData.category === cat,
209
+ })) : []), [feedbackData.type, feedbackData.category]);
210
+
211
+ const priorityData = useMemo(() => PRIORITY_LEVELS.map(p => ({
212
+ ...p,
213
+ isSelected: feedbackData.priority === p.id,
214
+ })), [feedbackData.priority]);
215
+
216
+ const renderProgress = () => (
217
+ <View
218
+ className="flex-row justify-center gap-space-8 pt-space-8 pb-space-16"
219
+ accessibilityRole="progressbar"
220
+ accessibilityLabel={`Step ${currentStep + 1} of ${TOTAL_STEPS}`}
221
+ >
222
+ {Array.from({ length: TOTAL_STEPS }, (_, index) => (
223
+ <View
224
+ key={index}
225
+ className={
226
+ currentStep === index
227
+ ? 'h-space-8 rounded-radius-max bg-fill-brand'
228
+ : 'h-space-8 rounded-radius-max bg-fill-secondary'
229
+ }
230
+ style={currentStep === index ? styles.progressDotActive : styles.progressDot}
231
+ />
232
+ ))}
233
+ </View>
234
+ );
235
+
236
+ const renderStepHeader = (title: string, subtitle: string) => (
237
+ <View className="w-full gap-space-8 mb-space-24">
238
+ <H2 className="text-headerBold font-headerBold text-text">{title}</H2>
239
+ <Text className="text-body font-body text-text-secondary">{subtitle}</Text>
240
+ </View>
241
+ );
242
+
243
+ const renderTypeStep = () => (
244
+ <Animated.View style={[styles.stepContainer, { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }]}>
245
+ {renderStepHeader(
246
+ t('feedback.type.title') || 'What type of feedback?',
247
+ t('feedback.type.subtitle') || 'Choose the category that best describes your feedback',
248
+ )}
249
+
250
+ <View className="w-full">
251
+ <SettingsListGroup>
252
+ {feedbackTypeData.map(type => (
253
+ <SettingsListItem
254
+ key={type.id}
255
+ icon={<SettingsIcon name={TYPE_ICON_GLYPH[type.id]} color={typeColor(type.id)} />}
256
+ title={type.label}
257
+ description={type.description}
258
+ onPress={() => { updateField('type', type.id); updateField('category', ''); }}
259
+ showChevron={false}
260
+ />
261
+ ))}
262
+ </SettingsListGroup>
263
+ </View>
264
+
265
+ {feedbackData.type ? (
266
+ <View className="w-full mt-space-24">
267
+ <Text className="text-caption font-caption text-text-secondary mb-space-8">
268
+ {t('feedback.category.label') || 'Category'}
269
+ </Text>
270
+ <View className="w-full">
271
+ <SettingsListGroup>
272
+ {categoryData.map(cat => (
273
+ <SettingsListItem
274
+ key={cat.name}
275
+ icon={(
276
+ <SettingsIcon
277
+ name={cat.isSelected ? 'check-circle' : 'circle-outline'}
278
+ color={cat.isSelected ? colors.primary : colors.textSecondary}
279
+ />
280
+ )}
281
+ title={cat.name}
282
+ onPress={() => updateField('category', cat.name)}
283
+ showChevron={false}
284
+ />
285
+ ))}
286
+ </SettingsListGroup>
287
+ </View>
288
+ </View>
289
+ ) : null}
290
+
291
+ <View className="flex-row gap-space-8 mt-space-24 w-full">
292
+ <Button
293
+ variant="secondary"
294
+ onPress={goBack}
295
+ accessibilityLabel="Go back"
296
+ icon={<Ionicons name="arrow-back" size={16} color={colors.text} />}
297
+ style={styles.navButton}
298
+ >
299
+ {t('common.actions.back') || 'Back'}
300
+ </Button>
301
+
302
+ <Button
303
+ variant="primary"
304
+ onPress={nextStep}
305
+ disabled={!isTypeStepValid()}
306
+ accessibilityLabel="Continue to next step"
307
+ iconPosition="right"
308
+ icon={<Ionicons name="arrow-forward" size={16} color={colors.primaryForeground} />}
309
+ style={styles.navButton}
310
+ >
311
+ {t('common.actions.next') || 'Next'}
312
+ </Button>
313
+ </View>
314
+ </Animated.View>
315
+ );
316
+
317
+ const renderDetailsStep = () => (
318
+ <Animated.View style={[styles.stepContainer, { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }]}>
319
+ {renderStepHeader(
320
+ t('feedback.details.title') || 'Tell us more',
321
+ t('feedback.details.subtitle') || 'Provide details about your feedback',
322
+ )}
323
+
324
+ <View className="w-full gap-space-16">
325
+ <TextField>
326
+ <TextFieldInput
327
+ floatingLabel
328
+ label={t('feedback.fields.title.label') || 'Title'}
329
+ value={feedbackData.title}
330
+ onChangeText={(text) => { updateField('title', text); setErrorMessage(''); }}
331
+ placeholder={t('feedback.fields.title.placeholder') || 'Brief summary of your feedback'}
332
+ testID="feedback-title-input"
333
+ accessibilityLabel="Feedback title"
334
+ accessibilityHint="Enter a brief summary of your feedback"
335
+ />
336
+ </TextField>
337
+
338
+ <TextField>
339
+ <TextFieldInput
340
+ floatingLabel
341
+ multiline
342
+ numberOfLines={6}
343
+ label={t('feedback.fields.description.label') || 'Description'}
344
+ value={feedbackData.description}
345
+ onChangeText={(text) => { updateField('description', text); setErrorMessage(''); }}
346
+ placeholder={t('feedback.fields.description.placeholder') || 'Please provide detailed information...'}
347
+ testID="feedback-description-input"
348
+ accessibilityLabel="Feedback description"
349
+ accessibilityHint="Provide detailed information about your feedback"
350
+ />
351
+ </TextField>
352
+ </View>
353
+
354
+ <View className="w-full mt-space-24">
355
+ <Text className="text-caption font-caption text-text-secondary mb-space-8">
356
+ {t('feedback.priority.label') || 'Priority Level'}
357
+ </Text>
358
+ <View className="w-full">
359
+ <SettingsListGroup>
360
+ {priorityData.map(p => (
361
+ <SettingsListItem
362
+ key={p.id}
363
+ icon={<SettingsIcon name={PRIORITY_ICON_GLYPH[p.id]} color={priorityColor(p.id)} />}
364
+ title={p.label}
365
+ onPress={() => updateField('priority', p.id)}
366
+ showChevron={false}
367
+ />
368
+ ))}
369
+ </SettingsListGroup>
370
+ </View>
371
+ </View>
372
+
373
+ <View className="flex-row gap-space-8 mt-space-24 w-full">
374
+ <Button
375
+ variant="secondary"
376
+ onPress={prevStep}
377
+ accessibilityLabel="Go back"
378
+ icon={<Ionicons name="arrow-back" size={16} color={colors.text} />}
379
+ style={styles.navButton}
380
+ >
381
+ {t('common.actions.back') || 'Back'}
382
+ </Button>
383
+
384
+ <Button
385
+ variant="primary"
386
+ onPress={nextStep}
387
+ disabled={!isDetailsStepValid()}
388
+ accessibilityLabel="Continue to next step"
389
+ iconPosition="right"
390
+ icon={<Ionicons name="arrow-forward" size={16} color={colors.primaryForeground} />}
391
+ style={styles.navButton}
392
+ >
393
+ {t('common.actions.next') || 'Next'}
394
+ </Button>
395
+ </View>
396
+ </Animated.View>
397
+ );
398
+
399
+ const renderContactStep = () => (
400
+ <Animated.View style={[styles.stepContainer, { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }]}>
401
+ {renderStepHeader(
402
+ t('feedback.contact.title') || 'Contact Information',
403
+ t('feedback.contact.subtitle') || 'Help us get back to you',
404
+ )}
405
+
406
+ <View className="w-full">
407
+ <TextField>
408
+ <TextFieldInput
409
+ floatingLabel
410
+ label={t('feedback.fields.email.label') || 'Email Address'}
411
+ value={feedbackData.contactEmail}
412
+ onChangeText={(text) => { updateField('contactEmail', text); setErrorMessage(''); }}
413
+ placeholder={user?.email || (t('feedback.fields.email.placeholder') || 'Enter your email address')}
414
+ keyboardType="email-address"
415
+ autoCapitalize="none"
416
+ autoCorrect={false}
417
+ testID="feedback-email-input"
418
+ accessibilityLabel="Email address"
419
+ accessibilityHint="Enter your email so we can respond"
420
+ />
421
+ </TextField>
422
+ </View>
423
+
424
+ <View className="w-full mt-space-16">
425
+ <SettingsListGroup>
426
+ <SettingsListItem
427
+ icon={<SettingsIcon name="information" color={colors.info} />}
428
+ title={t('feedback.contact.includeSystemInfo') || 'Include system information to help us better understand your issue'}
429
+ rightElement={(
430
+ <Switch
431
+ value={feedbackData.systemInfo}
432
+ onValueChange={(value) => updateField('systemInfo', value)}
433
+ testID="feedback-system-info-switch"
434
+ />
435
+ )}
436
+ showChevron={false}
437
+ />
438
+ </SettingsListGroup>
439
+ </View>
440
+
441
+ <View className="flex-row gap-space-8 mt-space-24 w-full">
442
+ <Button
443
+ variant="secondary"
444
+ onPress={prevStep}
445
+ accessibilityLabel="Go back"
446
+ icon={<Ionicons name="arrow-back" size={16} color={colors.text} />}
447
+ style={styles.navButton}
448
+ >
449
+ {t('common.actions.back') || 'Back'}
450
+ </Button>
451
+
452
+ <Button
453
+ variant="primary"
454
+ onPress={nextStep}
455
+ disabled={!isContactStepValid()}
456
+ accessibilityLabel="Continue to summary"
457
+ iconPosition="right"
458
+ icon={<Ionicons name="arrow-forward" size={16} color={colors.primaryForeground} />}
459
+ style={styles.navButton}
460
+ >
461
+ {t('common.actions.next') || 'Next'}
462
+ </Button>
463
+ </View>
464
+ </Animated.View>
465
+ );
466
+
467
+ const renderSummaryRow = (label: string, value: string | undefined) => (
468
+ <View className="flex-row gap-space-12">
469
+ <Text className="text-body font-body text-text-secondary" style={styles.summaryLabel}>{label}</Text>
470
+ <Text className="text-body font-body text-text flex-1">{value}</Text>
471
+ </View>
472
+ );
473
+
474
+ const renderSummaryStep = () => (
475
+ <Animated.View style={[styles.stepContainer, { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }]}>
476
+ {renderStepHeader(
477
+ t('feedback.summary.title') || 'Summary',
478
+ t('feedback.summary.subtitle') || 'Please review your feedback before submitting',
479
+ )}
480
+
481
+ <View className="w-full gap-space-12 p-space-16 rounded-radius-20 bg-fill mb-space-24">
482
+ {renderSummaryRow(
483
+ t('feedback.summary.type') || 'Type:',
484
+ FEEDBACK_TYPES.find(ft => ft.id === feedbackData.type)?.label,
485
+ )}
486
+ {renderSummaryRow(
487
+ t('feedback.summary.category') || 'Category:',
488
+ feedbackData.category,
489
+ )}
490
+ {renderSummaryRow(
491
+ t('feedback.summary.priority') || 'Priority:',
492
+ PRIORITY_LEVELS.find(p => p.id === feedbackData.priority)?.label,
493
+ )}
494
+ {renderSummaryRow(
495
+ t('feedback.summary.titleField') || 'Title:',
496
+ feedbackData.title,
497
+ )}
498
+ {renderSummaryRow(
499
+ t('feedback.summary.contact') || 'Contact:',
500
+ feedbackData.contactEmail || user?.email,
501
+ )}
502
+ </View>
503
+
504
+ <Button
505
+ variant="primary"
506
+ onPress={handleSubmitFeedback}
507
+ disabled={feedbackState.status === 'submitting'}
508
+ loading={feedbackState.status === 'submitting'}
509
+ testID="submit-feedback-button"
510
+ accessibilityLabel="Submit feedback"
511
+ iconPosition="right"
512
+ icon={<Ionicons name="send" size={18} color={colors.primaryForeground} />}
513
+ style={styles.fullWidthButton}
514
+ >
515
+ {t('feedback.actions.submit') || 'Submit Feedback'}
516
+ </Button>
517
+
518
+ <View className="flex-row mt-space-16 w-full">
519
+ <Button
520
+ variant="secondary"
521
+ onPress={prevStep}
522
+ accessibilityLabel="Go back"
523
+ icon={<Ionicons name="arrow-back" size={16} color={colors.text} />}
524
+ style={styles.navButton}
525
+ >
526
+ {t('common.actions.back') || 'Back'}
527
+ </Button>
528
+ </View>
529
+ </Animated.View>
530
+ );
531
+
532
+ const renderSuccessStep = () => (
533
+ <Animated.View style={[styles.stepContainer, { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }]}>
534
+ <View className="w-full items-center justify-center p-space-32 gap-space-16">
535
+ <View className="p-space-24 rounded-radius-max bg-fill-secondary">
536
+ <Ionicons name="checkmark-circle" size={48} color={colors.success} />
537
+ </View>
538
+ <H2 className="text-headerBold font-headerBold text-text text-center">
539
+ {t('feedback.success.thanks') || 'Thank You!'}
540
+ </H2>
541
+ <Text className="text-body font-body text-text-secondary text-center">
542
+ {t('feedback.success.message') || "Your feedback has been submitted successfully. We'll review it and get back to you soon."}
543
+ </Text>
544
+ <Button
545
+ variant="primary"
546
+ onPress={() => { resetForm(); setCurrentStep(0); }}
547
+ accessibilityLabel="Submit another feedback"
548
+ style={styles.fullWidthButton}
549
+ >
550
+ {t('feedback.actions.submitAnother') || 'Submit Another'}
551
+ </Button>
552
+ </View>
553
+ </Animated.View>
554
+ );
555
+
556
+ const renderCurrentStep = () => {
557
+ if (feedbackState.status === 'success') return renderSuccessStep();
558
+ switch (currentStep) {
559
+ case 0: return renderTypeStep();
560
+ case 1: return renderDetailsStep();
561
+ case 2: return renderContactStep();
562
+ case 3: return renderSummaryStep();
563
+ default: return renderTypeStep();
564
+ }
565
+ };
566
+
567
+ return (
568
+ <>
569
+
570
+ <View className="px-screen-margin pt-space-24 pb-space-32">
571
+ {feedbackState.status !== 'success' ? renderProgress() : null}
572
+ {renderCurrentStep()}
573
+ </View>
574
+ </>
575
+ );
742
576
  };
743
577
 
744
578
  const styles = StyleSheet.create({
745
- stepContainer: {
746
- flex: 1,
747
- alignItems: "flex-start",
748
- },
749
- navButton: {
750
- flex: 1,
751
- },
752
- fullWidthButton: {
753
- width: "100%",
754
- },
755
- summaryLabel: {
756
- width: 90,
757
- },
758
- progressDot: {
759
- width: 8,
760
- },
761
- progressDotActive: {
762
- width: 24,
763
- },
579
+ stepContainer: {
580
+ flex: 1,
581
+ alignItems: 'flex-start',
582
+ },
583
+ navButton: {
584
+ flex: 1,
585
+ },
586
+ fullWidthButton: {
587
+ width: '100%',
588
+ },
589
+ summaryLabel: {
590
+ width: 90,
591
+ },
592
+ progressDot: {
593
+ width: 8,
594
+ },
595
+ progressDotActive: {
596
+ width: 24,
597
+ },
764
598
  });
765
599
 
766
600
  export default FeedbackScreen;