@oxyhq/services 6.9.4 → 6.9.6

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 (299) hide show
  1. package/lib/commonjs/ui/client.js +0 -7
  2. package/lib/commonjs/ui/client.js.map +1 -1
  3. package/lib/commonjs/ui/components/BottomSheet.js +5 -3
  4. package/lib/commonjs/ui/components/BottomSheet.js.map +1 -1
  5. package/lib/commonjs/ui/components/FontLoader.js +1 -1
  6. package/lib/commonjs/ui/components/FontLoader.js.map +1 -1
  7. package/lib/commonjs/ui/components/Header.js.map +1 -1
  8. package/lib/commonjs/ui/components/HelperText.js +1 -1
  9. package/lib/commonjs/ui/components/HelperText.js.map +1 -1
  10. package/lib/commonjs/ui/components/Icon.js +6 -2
  11. package/lib/commonjs/ui/components/Icon.js.map +1 -1
  12. package/lib/commonjs/ui/components/OxyProvider.js +9 -1
  13. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  14. package/lib/commonjs/ui/components/QuickActions.js.map +1 -1
  15. package/lib/commonjs/ui/components/SignInModal.js +5 -4
  16. package/lib/commonjs/ui/components/SignInModal.js.map +1 -1
  17. package/lib/commonjs/ui/components/TouchableRipple/Pressable.js.map +1 -1
  18. package/lib/commonjs/ui/components/feedback/FormInput.js.map +1 -1
  19. package/lib/commonjs/ui/components/fileManagement/AnimatedButton.js.map +1 -1
  20. package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -1
  21. package/lib/commonjs/ui/components/modals/DeleteAccountModal.js +1 -1
  22. package/lib/commonjs/ui/components/modals/DeleteAccountModal.js.map +1 -1
  23. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js +26 -20
  24. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  25. package/lib/commonjs/ui/components/payment/PaymentMethodStep.js +9 -5
  26. package/lib/commonjs/ui/components/payment/PaymentMethodStep.js.map +1 -1
  27. package/lib/commonjs/ui/components/payment/PaymentReviewStep.js +19 -13
  28. package/lib/commonjs/ui/components/payment/PaymentReviewStep.js.map +1 -1
  29. package/lib/commonjs/ui/components/payment/PaymentSuccessStep.js +9 -5
  30. package/lib/commonjs/ui/components/payment/PaymentSuccessStep.js.map +1 -1
  31. package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js +14 -10
  32. package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js.map +1 -1
  33. package/lib/commonjs/ui/components/types.js +4 -0
  34. package/lib/commonjs/ui/hooks/useAssets.js +4 -4
  35. package/lib/commonjs/ui/hooks/useAssets.js.map +1 -1
  36. package/lib/commonjs/ui/hooks/useAsyncAction.js +2 -2
  37. package/lib/commonjs/ui/hooks/useAsyncAction.js.map +1 -1
  38. package/lib/commonjs/ui/hooks/useFollow.js.map +1 -1
  39. package/lib/commonjs/ui/hooks/useProfileEditing.js.map +1 -1
  40. package/lib/commonjs/ui/hooks/useSettingToggle.js +2 -2
  41. package/lib/commonjs/ui/hooks/useSettingToggle.js.map +1 -1
  42. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +3 -3
  43. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  44. package/lib/commonjs/ui/screens/AccountVerificationScreen.js +1 -1
  45. package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
  46. package/lib/commonjs/ui/screens/AppInfoScreen.js +66 -60
  47. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  48. package/lib/commonjs/ui/screens/FeedbackScreen.js +2 -2
  49. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  50. package/lib/commonjs/ui/screens/FileManagementScreen.js +139 -79
  51. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  52. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +2 -2
  53. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  54. package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js +22 -17
  55. package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
  56. package/lib/commonjs/ui/screens/OxyAuthScreen.js +2 -2
  57. package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
  58. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +6 -2
  59. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  60. package/lib/commonjs/ui/screens/SessionManagementScreen.js +39 -29
  61. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  62. package/lib/commonjs/ui/screens/UserLinksScreen.js +11 -3
  63. package/lib/commonjs/ui/screens/UserLinksScreen.js.map +1 -1
  64. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +1 -1
  65. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  66. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  67. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  68. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -1
  69. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  70. package/lib/commonjs/ui/stores/followStore.js +2 -2
  71. package/lib/commonjs/ui/stores/followStore.js.map +1 -1
  72. package/lib/commonjs/ui/utils/errorHandlers.js +2 -2
  73. package/lib/commonjs/ui/utils/errorHandlers.js.map +1 -1
  74. package/lib/commonjs/ui/utils/fileManagement.js +8 -3
  75. package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
  76. package/lib/commonjs/ui/utils/sessionHelpers.js +3 -2
  77. package/lib/commonjs/ui/utils/sessionHelpers.js.map +1 -1
  78. package/lib/commonjs/ui/utils/storageHelpers.js +1 -1
  79. package/lib/commonjs/ui/utils/storageHelpers.js.map +1 -1
  80. package/lib/commonjs/utils/hookUtils.js +4 -0
  81. package/lib/commonjs/utils/hookUtils.js.map +1 -1
  82. package/lib/module/ui/client.js +0 -1
  83. package/lib/module/ui/client.js.map +1 -1
  84. package/lib/module/ui/components/BottomSheet.js +5 -3
  85. package/lib/module/ui/components/BottomSheet.js.map +1 -1
  86. package/lib/module/ui/components/FontLoader.js +1 -1
  87. package/lib/module/ui/components/FontLoader.js.map +1 -1
  88. package/lib/module/ui/components/Header.js.map +1 -1
  89. package/lib/module/ui/components/HelperText.js +1 -1
  90. package/lib/module/ui/components/HelperText.js.map +1 -1
  91. package/lib/module/ui/components/Icon.js +6 -2
  92. package/lib/module/ui/components/Icon.js.map +1 -1
  93. package/lib/module/ui/components/OxyProvider.js +9 -1
  94. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  95. package/lib/module/ui/components/QuickActions.js.map +1 -1
  96. package/lib/module/ui/components/SignInModal.js +5 -4
  97. package/lib/module/ui/components/SignInModal.js.map +1 -1
  98. package/lib/module/ui/components/TouchableRipple/Pressable.js.map +1 -1
  99. package/lib/module/ui/components/feedback/FormInput.js.map +1 -1
  100. package/lib/module/ui/components/fileManagement/AnimatedButton.js.map +1 -1
  101. package/lib/module/ui/components/icon/OxyIcon.js.map +1 -1
  102. package/lib/module/ui/components/modals/DeleteAccountModal.js +1 -1
  103. package/lib/module/ui/components/modals/DeleteAccountModal.js.map +1 -1
  104. package/lib/module/ui/components/payment/PaymentDetailsStep.js +26 -20
  105. package/lib/module/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  106. package/lib/module/ui/components/payment/PaymentMethodStep.js +9 -5
  107. package/lib/module/ui/components/payment/PaymentMethodStep.js.map +1 -1
  108. package/lib/module/ui/components/payment/PaymentReviewStep.js +19 -13
  109. package/lib/module/ui/components/payment/PaymentReviewStep.js.map +1 -1
  110. package/lib/module/ui/components/payment/PaymentSuccessStep.js +9 -5
  111. package/lib/module/ui/components/payment/PaymentSuccessStep.js.map +1 -1
  112. package/lib/module/ui/components/payment/PaymentSummaryStep.js +14 -10
  113. package/lib/module/ui/components/payment/PaymentSummaryStep.js.map +1 -1
  114. package/lib/module/ui/components/types.js +2 -0
  115. package/lib/module/ui/hooks/useAssets.js +4 -4
  116. package/lib/module/ui/hooks/useAssets.js.map +1 -1
  117. package/lib/module/ui/hooks/useAsyncAction.js +2 -2
  118. package/lib/module/ui/hooks/useAsyncAction.js.map +1 -1
  119. package/lib/module/ui/hooks/useFollow.js.map +1 -1
  120. package/lib/module/ui/hooks/useProfileEditing.js.map +1 -1
  121. package/lib/module/ui/hooks/useSettingToggle.js +2 -2
  122. package/lib/module/ui/hooks/useSettingToggle.js.map +1 -1
  123. package/lib/module/ui/screens/AccountOverviewScreen.js +3 -3
  124. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  125. package/lib/module/ui/screens/AccountVerificationScreen.js +1 -1
  126. package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
  127. package/lib/module/ui/screens/AppInfoScreen.js +66 -60
  128. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  129. package/lib/module/ui/screens/FeedbackScreen.js +2 -2
  130. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  131. package/lib/module/ui/screens/FileManagementScreen.js +139 -79
  132. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  133. package/lib/module/ui/screens/LanguageSelectorScreen.js +2 -2
  134. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  135. package/lib/module/ui/screens/LearnMoreUsernamesScreen.js +22 -17
  136. package/lib/module/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
  137. package/lib/module/ui/screens/OxyAuthScreen.js +2 -2
  138. package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
  139. package/lib/module/ui/screens/PaymentGatewayScreen.js +6 -2
  140. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  141. package/lib/module/ui/screens/SessionManagementScreen.js +39 -29
  142. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  143. package/lib/module/ui/screens/UserLinksScreen.js +11 -3
  144. package/lib/module/ui/screens/UserLinksScreen.js.map +1 -1
  145. package/lib/module/ui/screens/WelcomeNewUserScreen.js +1 -1
  146. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  147. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  148. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  149. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
  150. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  151. package/lib/module/ui/stores/followStore.js +2 -2
  152. package/lib/module/ui/stores/followStore.js.map +1 -1
  153. package/lib/module/ui/utils/errorHandlers.js +2 -2
  154. package/lib/module/ui/utils/errorHandlers.js.map +1 -1
  155. package/lib/module/ui/utils/fileManagement.js +8 -3
  156. package/lib/module/ui/utils/fileManagement.js.map +1 -1
  157. package/lib/module/ui/utils/sessionHelpers.js +3 -2
  158. package/lib/module/ui/utils/sessionHelpers.js.map +1 -1
  159. package/lib/module/ui/utils/storageHelpers.js +1 -1
  160. package/lib/module/ui/utils/storageHelpers.js.map +1 -1
  161. package/lib/module/utils/hookUtils.js +4 -0
  162. package/lib/module/utils/hookUtils.js.map +1 -1
  163. package/lib/typescript/commonjs/ui/client.d.ts +0 -1
  164. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  165. package/lib/typescript/commonjs/ui/components/BottomSheet.d.ts.map +1 -1
  166. package/lib/typescript/commonjs/ui/components/Icon.d.ts.map +1 -1
  167. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  168. package/lib/typescript/commonjs/ui/components/SignInModal.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/ui/components/TextField/Adornment/types.d.ts +1 -1
  170. package/lib/typescript/commonjs/ui/components/TextField/Adornment/types.d.ts.map +1 -1
  171. package/lib/typescript/commonjs/ui/components/TouchableRipple/Pressable.d.ts.map +1 -1
  172. package/lib/typescript/commonjs/ui/components/fileManagement/AnimatedButton.d.ts +1 -1
  173. package/lib/typescript/commonjs/ui/components/fileManagement/AnimatedButton.d.ts.map +1 -1
  174. package/lib/typescript/commonjs/ui/components/payment/PaymentDetailsStep.d.ts.map +1 -1
  175. package/lib/typescript/commonjs/ui/components/payment/PaymentMethodStep.d.ts.map +1 -1
  176. package/lib/typescript/commonjs/ui/components/payment/PaymentReviewStep.d.ts.map +1 -1
  177. package/lib/typescript/commonjs/ui/components/payment/PaymentSuccessStep.d.ts.map +1 -1
  178. package/lib/typescript/commonjs/ui/components/payment/PaymentSummaryStep.d.ts.map +1 -1
  179. package/lib/typescript/commonjs/ui/components/types.d.ts +18 -17
  180. package/lib/typescript/commonjs/ui/components/types.d.ts.map +1 -1
  181. package/lib/typescript/commonjs/ui/screens/AppInfoScreen.d.ts.map +1 -1
  182. package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
  183. package/lib/typescript/commonjs/ui/screens/LearnMoreUsernamesScreen.d.ts.map +1 -1
  184. package/lib/typescript/commonjs/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  185. package/lib/typescript/commonjs/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  186. package/lib/typescript/commonjs/ui/screens/UserLinksScreen.d.ts.map +1 -1
  187. package/lib/typescript/commonjs/ui/types/navigation.d.ts +2 -0
  188. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  189. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +1 -1
  190. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
  191. package/lib/typescript/commonjs/ui/utils/sessionHelpers.d.ts +2 -1
  192. package/lib/typescript/commonjs/ui/utils/sessionHelpers.d.ts.map +1 -1
  193. package/lib/typescript/commonjs/utils/hookUtils.d.ts.map +1 -1
  194. package/lib/typescript/module/ui/client.d.ts +0 -1
  195. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  196. package/lib/typescript/module/ui/components/BottomSheet.d.ts.map +1 -1
  197. package/lib/typescript/module/ui/components/Icon.d.ts.map +1 -1
  198. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  199. package/lib/typescript/module/ui/components/SignInModal.d.ts.map +1 -1
  200. package/lib/typescript/module/ui/components/TextField/Adornment/types.d.ts +1 -1
  201. package/lib/typescript/module/ui/components/TextField/Adornment/types.d.ts.map +1 -1
  202. package/lib/typescript/module/ui/components/TouchableRipple/Pressable.d.ts.map +1 -1
  203. package/lib/typescript/module/ui/components/fileManagement/AnimatedButton.d.ts +1 -1
  204. package/lib/typescript/module/ui/components/fileManagement/AnimatedButton.d.ts.map +1 -1
  205. package/lib/typescript/module/ui/components/payment/PaymentDetailsStep.d.ts.map +1 -1
  206. package/lib/typescript/module/ui/components/payment/PaymentMethodStep.d.ts.map +1 -1
  207. package/lib/typescript/module/ui/components/payment/PaymentReviewStep.d.ts.map +1 -1
  208. package/lib/typescript/module/ui/components/payment/PaymentSuccessStep.d.ts.map +1 -1
  209. package/lib/typescript/module/ui/components/payment/PaymentSummaryStep.d.ts.map +1 -1
  210. package/lib/typescript/module/ui/components/types.d.ts +18 -17
  211. package/lib/typescript/module/ui/components/types.d.ts.map +1 -1
  212. package/lib/typescript/module/ui/screens/AppInfoScreen.d.ts.map +1 -1
  213. package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
  214. package/lib/typescript/module/ui/screens/LearnMoreUsernamesScreen.d.ts.map +1 -1
  215. package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  216. package/lib/typescript/module/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  217. package/lib/typescript/module/ui/screens/UserLinksScreen.d.ts.map +1 -1
  218. package/lib/typescript/module/ui/types/navigation.d.ts +2 -0
  219. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  220. package/lib/typescript/module/ui/utils/fileManagement.d.ts +1 -1
  221. package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
  222. package/lib/typescript/module/ui/utils/sessionHelpers.d.ts +2 -1
  223. package/lib/typescript/module/ui/utils/sessionHelpers.d.ts.map +1 -1
  224. package/lib/typescript/module/utils/hookUtils.d.ts.map +1 -1
  225. package/package.json +1 -1
  226. package/src/ui/client.ts +0 -1
  227. package/src/ui/components/BottomSheet.tsx +4 -3
  228. package/src/ui/components/FontLoader.tsx +1 -1
  229. package/src/ui/components/Header.tsx +2 -2
  230. package/src/ui/components/HelperText.tsx +1 -1
  231. package/src/ui/components/Icon.tsx +2 -0
  232. package/src/ui/components/OxyProvider.tsx +6 -0
  233. package/src/ui/components/QuickActions.tsx +1 -1
  234. package/src/ui/components/SignInModal.tsx +6 -5
  235. package/src/ui/components/TextField/Adornment/types.tsx +1 -1
  236. package/src/ui/components/TouchableRipple/Pressable.tsx +1 -0
  237. package/src/ui/components/feedback/FormInput.tsx +1 -1
  238. package/src/ui/components/fileManagement/AnimatedButton.tsx +2 -2
  239. package/src/ui/components/icon/OxyIcon.tsx +1 -1
  240. package/src/ui/components/modals/DeleteAccountModal.tsx +2 -2
  241. package/src/ui/components/payment/PaymentDetailsStep.tsx +24 -22
  242. package/src/ui/components/payment/PaymentMethodStep.tsx +7 -5
  243. package/src/ui/components/payment/PaymentReviewStep.tsx +15 -13
  244. package/src/ui/components/payment/PaymentSuccessStep.tsx +7 -5
  245. package/src/ui/components/payment/PaymentSummaryStep.tsx +12 -10
  246. package/src/ui/components/types.tsx +19 -17
  247. package/src/ui/hooks/useAssets.ts +8 -8
  248. package/src/ui/hooks/useAsyncAction.ts +4 -4
  249. package/src/ui/hooks/useFollow.ts +1 -1
  250. package/src/ui/hooks/useProfileEditing.ts +1 -1
  251. package/src/ui/hooks/useSettingToggle.ts +4 -4
  252. package/src/ui/screens/AccountOverviewScreen.tsx +6 -6
  253. package/src/ui/screens/AccountVerificationScreen.tsx +2 -2
  254. package/src/ui/screens/AppInfoScreen.tsx +63 -61
  255. package/src/ui/screens/FeedbackScreen.tsx +3 -3
  256. package/src/ui/screens/FileManagementScreen.tsx +130 -121
  257. package/src/ui/screens/LanguageSelectorScreen.tsx +3 -3
  258. package/src/ui/screens/LearnMoreUsernamesScreen.tsx +22 -19
  259. package/src/ui/screens/OxyAuthScreen.tsx +3 -3
  260. package/src/ui/screens/PaymentGatewayScreen.tsx +4 -2
  261. package/src/ui/screens/SessionManagementScreen.tsx +30 -28
  262. package/src/ui/screens/UserLinksScreen.tsx +5 -3
  263. package/src/ui/screens/WelcomeNewUserScreen.tsx +2 -2
  264. package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +1 -1
  265. package/src/ui/screens/karma/KarmaRulesScreen.tsx +1 -1
  266. package/src/ui/stores/followStore.ts +4 -4
  267. package/src/ui/types/navigation.ts +2 -0
  268. package/src/ui/utils/errorHandlers.ts +2 -2
  269. package/src/ui/utils/fileManagement.ts +13 -8
  270. package/src/ui/utils/sessionHelpers.ts +3 -2
  271. package/src/ui/utils/storageHelpers.ts +1 -1
  272. package/src/utils/hookUtils.ts +4 -2
  273. package/lib/commonjs/ui/components/AnimationExample.js +0 -213
  274. package/lib/commonjs/ui/components/AnimationExample.js.map +0 -1
  275. package/lib/commonjs/ui/components/ErrorBoundary.js +0 -145
  276. package/lib/commonjs/ui/components/ErrorBoundary.js.map +0 -1
  277. package/lib/commonjs/ui/components/WebOxyProvider.js +0 -106
  278. package/lib/commonjs/ui/components/WebOxyProvider.js.map +0 -1
  279. package/lib/module/ui/components/AnimationExample.js +0 -209
  280. package/lib/module/ui/components/AnimationExample.js.map +0 -1
  281. package/lib/module/ui/components/ErrorBoundary.js +0 -139
  282. package/lib/module/ui/components/ErrorBoundary.js.map +0 -1
  283. package/lib/module/ui/components/WebOxyProvider.js +0 -102
  284. package/lib/module/ui/components/WebOxyProvider.js.map +0 -1
  285. package/lib/typescript/commonjs/ui/components/AnimationExample.d.ts +0 -4
  286. package/lib/typescript/commonjs/ui/components/AnimationExample.d.ts.map +0 -1
  287. package/lib/typescript/commonjs/ui/components/ErrorBoundary.d.ts +0 -31
  288. package/lib/typescript/commonjs/ui/components/ErrorBoundary.d.ts.map +0 -1
  289. package/lib/typescript/commonjs/ui/components/WebOxyProvider.d.ts +0 -52
  290. package/lib/typescript/commonjs/ui/components/WebOxyProvider.d.ts.map +0 -1
  291. package/lib/typescript/module/ui/components/AnimationExample.d.ts +0 -4
  292. package/lib/typescript/module/ui/components/AnimationExample.d.ts.map +0 -1
  293. package/lib/typescript/module/ui/components/ErrorBoundary.d.ts +0 -31
  294. package/lib/typescript/module/ui/components/ErrorBoundary.d.ts.map +0 -1
  295. package/lib/typescript/module/ui/components/WebOxyProvider.d.ts +0 -52
  296. package/lib/typescript/module/ui/components/WebOxyProvider.d.ts.map +0 -1
  297. package/src/ui/components/AnimationExample.tsx +0 -195
  298. package/src/ui/components/ErrorBoundary.tsx +0 -154
  299. package/src/ui/components/WebOxyProvider.tsx +0 -117
@@ -58,11 +58,11 @@ const LanguageSelectorScreen: React.FC<LanguageSelectorScreenProps> = ({
58
58
  if (isAuthenticated && user?.id) {
59
59
  try {
60
60
  await oxyServices.updateProfile({ language: languageId });
61
- } catch (e: any) {
61
+ } catch (e: unknown) {
62
62
  // Server sync failed, but we'll save locally anyway
63
63
  serverSyncFailed = true;
64
64
  if (__DEV__) {
65
- console.warn('Failed to sync language to server (will save locally only):', e?.message || e);
65
+ console.warn('Failed to sync language to server (will save locally only):', e instanceof Error ? e.message : e);
66
66
  }
67
67
  }
68
68
  }
@@ -89,7 +89,7 @@ const LanguageSelectorScreen: React.FC<LanguageSelectorScreenProps> = ({
89
89
  if (__DEV__) {
90
90
  console.error('Error saving language preference:', error);
91
91
  }
92
- toast.error('Failed to save language preference');
92
+ toast.error(t('language.saveFailed'));
93
93
  setIsLoading(false);
94
94
  }
95
95
  }, [currentLanguage, isLoading, isAuthenticated, user?.id, oxyServices, setLanguage, t, onClose, goBack]);
@@ -10,43 +10,44 @@ import {
10
10
  import { Ionicons } from '@expo/vector-icons';
11
11
  import type { BaseScreenProps } from '../types/navigation';
12
12
  import { useThemeStyles } from '../hooks/useThemeStyles';
13
+ import { useI18n } from '../hooks/useI18n';
13
14
 
14
15
  interface InfoSection {
15
16
  id: string;
16
- title: string;
17
- content: string;
17
+ titleKey: string;
18
+ contentKey: string;
18
19
  icon: string;
19
20
  }
20
21
 
21
22
  const INFO_SECTIONS: InfoSection[] = [
22
23
  {
23
24
  id: 'what',
24
- title: 'What is a username?',
25
- content: 'Your username is your unique identifier on Oxy. It\'s how other people find and mention you. Think of it like your handle on social media - it\'s public and represents your identity across all Oxy apps.',
25
+ titleKey: 'learnMoreUsernames.sections.what.title',
26
+ contentKey: 'learnMoreUsernames.sections.what.content',
26
27
  icon: 'at-outline',
27
28
  },
28
29
  {
29
30
  id: 'rules',
30
- title: 'Username rules',
31
- content: 'Usernames can only contain lowercase letters (a-z) and numbers (0-9). They must be at least 4 characters long. Special characters, spaces, and uppercase letters are not allowed to keep usernames simple and easy to remember.',
31
+ titleKey: 'learnMoreUsernames.sections.rules.title',
32
+ contentKey: 'learnMoreUsernames.sections.rules.content',
32
33
  icon: 'list-outline',
33
34
  },
34
35
  {
35
36
  id: 'unique',
36
- title: 'Why must it be unique?',
37
- content: 'Each username can only belong to one person. This ensures that when someone searches for you or mentions you, they find the right person. It also prevents confusion and impersonation.',
37
+ titleKey: 'learnMoreUsernames.sections.unique.title',
38
+ contentKey: 'learnMoreUsernames.sections.unique.content',
38
39
  icon: 'finger-print-outline',
39
40
  },
40
41
  {
41
42
  id: 'change',
42
- title: 'Can I change it later?',
43
- content: 'Yes! You can change your username anytime in your account settings. Keep in mind that your old username will become available for others to use, and people who knew your old username will need to find you with the new one.',
43
+ titleKey: 'learnMoreUsernames.sections.change.title',
44
+ contentKey: 'learnMoreUsernames.sections.change.content',
44
45
  icon: 'refresh-outline',
45
46
  },
46
47
  {
47
48
  id: 'tips',
48
- title: 'Tips for choosing a username',
49
- content: 'Choose something memorable and easy to spell. Avoid using personal information like your birth year or phone number. Consider using a name that represents you across all contexts - professional and personal.',
49
+ titleKey: 'learnMoreUsernames.sections.tips.title',
50
+ contentKey: 'learnMoreUsernames.sections.tips.content',
50
51
  icon: 'bulb-outline',
51
52
  },
52
53
  ];
@@ -55,6 +56,7 @@ const LearnMoreUsernamesScreen: React.FC<BaseScreenProps> = ({
55
56
  theme,
56
57
  }) => {
57
58
  const themeStyles = useThemeStyles(theme || 'light');
59
+ const { t } = useI18n();
58
60
  const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set(['what'])); // Start with first section expanded
59
61
 
60
62
  const toggleExpanded = useCallback((id: string) => {
@@ -83,15 +85,16 @@ const LearnMoreUsernamesScreen: React.FC<BaseScreenProps> = ({
83
85
  <Ionicons name="at" size={32} color={themeStyles.primaryColor} />
84
86
  </View>
85
87
  <Text style={[styles.introTitle, { color: themeStyles.textColor }]}>
86
- Your unique identity
88
+ {t('learnMoreUsernames.introTitle')}
87
89
  </Text>
88
90
  <Text style={[styles.introText, { color: themeStyles.mutedTextColor }]}>
89
- Your username is how people find and recognize you across all Oxy apps.
91
+ {t('learnMoreUsernames.introText')}
90
92
  </Text>
91
93
  </View>
92
94
 
93
95
  {INFO_SECTIONS.map((section, index) => {
94
96
  const isExpanded = expandedIds.has(section.id);
97
+ const sectionTitle = t(section.titleKey);
95
98
  return (
96
99
  <View
97
100
  key={section.id}
@@ -105,8 +108,8 @@ const LearnMoreUsernamesScreen: React.FC<BaseScreenProps> = ({
105
108
  style={styles.sectionHeader}
106
109
  onPress={() => toggleExpanded(section.id)}
107
110
  accessibilityRole="button"
108
- accessibilityLabel={section.title}
109
- accessibilityHint={isExpanded ? 'Collapse section' : 'Expand section'}
111
+ accessibilityLabel={sectionTitle}
112
+ accessibilityHint={isExpanded ? t('learnMoreUsernames.collapseHint') : t('learnMoreUsernames.expandHint')}
110
113
  accessibilityState={{ expanded: isExpanded }}
111
114
  >
112
115
  <View style={[styles.sectionIconContainer, { backgroundColor: `${themeStyles.primaryColor}15` }]}>
@@ -117,7 +120,7 @@ const LearnMoreUsernamesScreen: React.FC<BaseScreenProps> = ({
117
120
  />
118
121
  </View>
119
122
  <Text style={[styles.sectionTitle, { color: themeStyles.textColor }]}>
120
- {section.title}
123
+ {sectionTitle}
121
124
  </Text>
122
125
  <Ionicons
123
126
  name={isExpanded ? 'chevron-up' : 'chevron-down'}
@@ -128,7 +131,7 @@ const LearnMoreUsernamesScreen: React.FC<BaseScreenProps> = ({
128
131
  {isExpanded && (
129
132
  <View style={[styles.sectionContent, { borderTopColor: themeStyles.borderColor }]}>
130
133
  <Text style={[styles.sectionText, { color: themeStyles.mutedTextColor }]}>
131
- {section.content}
134
+ {t(section.contentKey)}
132
135
  </Text>
133
136
  </View>
134
137
  )}
@@ -138,7 +141,7 @@ const LearnMoreUsernamesScreen: React.FC<BaseScreenProps> = ({
138
141
 
139
142
  <View style={styles.footer}>
140
143
  <Text style={[styles.footerText, { color: themeStyles.mutedTextColor }]}>
141
- Need more help? Visit our Help Center for additional information.
144
+ {t('learnMoreUsernames.footer')}
142
145
  </Text>
143
146
  </View>
144
147
  </ScrollView>
@@ -200,7 +200,7 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
200
200
  });
201
201
 
202
202
  socket.on('connect_error', (err) => {
203
- debug.log('Socket connection error, falling back to polling:', err.message);
203
+ debug.log('Socket connection error, falling back to polling:', (err instanceof Error ? err.message : null));
204
204
  // Fall back to polling if socket fails
205
205
  socket.disconnect();
206
206
  startPolling(sessionToken);
@@ -281,8 +281,8 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
281
281
 
282
282
  // Try socket first, will fall back to polling if needed
283
283
  connectSocket(sessionToken);
284
- } catch (err: any) {
285
- setError(err.message || 'Failed to create auth session');
284
+ } catch (err: unknown) {
285
+ setError((err instanceof Error ? err.message : null) || 'Failed to create auth session');
286
286
  } finally {
287
287
  setIsLoading(false);
288
288
  }
@@ -13,6 +13,7 @@ import { useThemeColors } from '../styles';
13
13
  import { normalizeTheme } from '../utils/themeUtils';
14
14
  import GroupedPillButtons from '../components/internal/GroupedPillButtons';
15
15
  import { useThemeStyles } from '../hooks/useThemeStyles';
16
+ import { useI18n } from '../hooks/useI18n';
16
17
  import QRCode from 'react-native-qrcode-svg';
17
18
 
18
19
  import {
@@ -80,6 +81,7 @@ const PaymentGatewayScreen: React.FC<PaymentGatewayScreenProps> = (props) => {
80
81
  const normalizedTheme = normalizeTheme(theme);
81
82
  const colors = useThemeColors(normalizedTheme);
82
83
  const themeStyles = useThemeStyles(normalizedTheme);
84
+ const { t } = useI18n();
83
85
  const styles = useMemo(() => createPaymentStyles(colors), [colors]);
84
86
 
85
87
  // Determine if the payment is for a recurring item (subscription)
@@ -183,11 +185,11 @@ const PaymentGatewayScreen: React.FC<PaymentGatewayScreenProps> = (props) => {
183
185
  if (!amount || Number.isNaN(Number(amount)) || Number(amount) <= 0) {
184
186
  return (
185
187
  <View style={styles.errorContainer}>
186
- <Text style={styles.errorText}>Invalid or missing payment amount.</Text>
188
+ <Text style={styles.errorText}>{t('payment.errors.invalidAmount')}</Text>
187
189
  <GroupedPillButtons
188
190
  buttons={[
189
191
  {
190
- text: 'Close',
192
+ text: t('payment.actions.close'),
191
193
  onPress: handleClose,
192
194
  icon: 'close',
193
195
  variant: 'primary',
@@ -20,6 +20,7 @@ import { Header, GroupedSection } from '../components';
20
20
  import { useThemeStyles } from '../hooks/useThemeStyles';
21
21
  import { normalizeTheme } from '../utils/themeUtils';
22
22
  import { useOxy } from '../context/OxyContext';
23
+ import { useI18n } from '../hooks/useI18n';
23
24
 
24
25
  // Button background colors for session actions
25
26
  const SWITCH_BUTTON_BG = {
@@ -46,6 +47,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
46
47
  logoutAll,
47
48
  switchSession,
48
49
  } = useOxy();
50
+ const { t } = useI18n();
49
51
  const [loading, setLoading] = useState(true);
50
52
  const [refreshing, setRefreshing] = useState(false);
51
53
  const [actionLoading, setActionLoading] = useState<string | null>(null);
@@ -74,11 +76,11 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
74
76
  console.error('Failed to load sessions:', error);
75
77
  }
76
78
  if (Platform.OS === 'web') {
77
- toast.error('Failed to load sessions. Please try again.');
79
+ toast.error(t('sessionManagement.toasts.loadFailed'));
78
80
  } else {
79
81
  Alert.alert(
80
82
  'Error',
81
- 'Failed to load sessions. Please try again.',
83
+ t('sessionManagement.toasts.loadFailed'),
82
84
  [{ text: 'OK' }]
83
85
  );
84
86
  }
@@ -90,17 +92,17 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
90
92
 
91
93
  // Memoized logout session handler - prevents unnecessary re-renders
92
94
  const handleLogoutSession = useCallback(async (sessionId: string) => {
93
- confirmAction('Are you sure you want to logout this session?', async () => {
95
+ confirmAction(t('sessionManagement.confirms.logoutSession'), async () => {
94
96
  try {
95
97
  setActionLoading(sessionId);
96
98
  await logout(sessionId);
97
99
  await refreshSessions();
98
- toast.success('Session logged out successfully');
100
+ toast.success(t('sessionManagement.toasts.logoutSuccess'));
99
101
  } catch (error) {
100
102
  if (__DEV__) {
101
103
  console.error('Logout session failed:', error);
102
104
  }
103
- toast.error('Failed to logout session. Please try again.');
105
+ toast.error(t('sessionManagement.toasts.logoutFailed'));
104
106
  } finally {
105
107
  setActionLoading(null);
106
108
  }
@@ -116,11 +118,11 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
116
118
  // Memoized logout other sessions handler - prevents unnecessary re-renders
117
119
  const handleLogoutOtherSessions = useCallback(async () => {
118
120
  if (otherSessionsCount === 0) {
119
- toast.info('No other sessions to logout.');
121
+ toast.info(t('sessionManagement.toasts.noOtherSessions'));
120
122
  return;
121
123
  }
122
124
  confirmAction(
123
- `This will logout ${otherSessionsCount} other session${otherSessionsCount > 1 ? 's' : ''}. Continue?`,
125
+ t('sessionManagement.confirms.logoutOthers', { count: otherSessionsCount }),
124
126
  async () => {
125
127
  try {
126
128
  setActionLoading('others');
@@ -130,12 +132,12 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
130
132
  }
131
133
  }
132
134
  await refreshSessions();
133
- toast.success('Other sessions logged out successfully');
135
+ toast.success(t('sessionManagement.toasts.logoutOthersSuccess'));
134
136
  } catch (error) {
135
137
  if (__DEV__) {
136
138
  console.error('Logout other sessions failed:', error);
137
139
  }
138
- toast.error('Failed to logout other sessions. Please try again.');
140
+ toast.error(t('sessionManagement.toasts.logoutOthersFailed'));
139
141
  } finally {
140
142
  setActionLoading(null);
141
143
  }
@@ -146,7 +148,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
146
148
  // Memoized logout all sessions handler - prevents unnecessary re-renders
147
149
  const handleLogoutAllSessions = useCallback(async () => {
148
150
  confirmAction(
149
- 'This will logout all sessions including this one and you will need to sign in again. Continue?',
151
+ t('sessionManagement.confirms.logoutAll'),
150
152
  async () => {
151
153
  try {
152
154
  setActionLoading('all');
@@ -155,7 +157,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
155
157
  if (__DEV__) {
156
158
  console.error('Logout all sessions failed:', error);
157
159
  }
158
- toast.error('Failed to logout all sessions. Please try again.');
160
+ toast.error(t('sessionManagement.toasts.logoutAllFailed'));
159
161
  } finally {
160
162
  setActionLoading(null);
161
163
  }
@@ -165,7 +167,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
165
167
 
166
168
  // Memoized relative time formatter - prevents function recreation on every render
167
169
  const formatRelative = useCallback((dateString?: string) => {
168
- if (!dateString) return 'Unknown';
170
+ if (!dateString) return t('appInfo.items.unknown');
169
171
  const date = new Date(dateString);
170
172
  const now = new Date();
171
173
  const diffMs = date.getTime() - now.getTime();
@@ -187,12 +189,12 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
187
189
  setSwitchLoading(sessionId);
188
190
  try {
189
191
  await switchSession(sessionId);
190
- toast.success('Switched session');
192
+ toast.success(t('sessionManagement.toasts.switchSuccess'));
191
193
  } catch (e) {
192
194
  if (__DEV__) {
193
195
  console.error('Switch session failed', e);
194
196
  }
195
- toast.error('Failed to switch session');
197
+ toast.error(t('sessionManagement.toasts.switchFailed'));
196
198
  } finally {
197
199
  setSwitchLoading(null);
198
200
  }
@@ -220,7 +222,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
220
222
  id: session.sessionId,
221
223
  icon: isCurrent ? 'shield-checkmark' : 'laptop-outline',
222
224
  iconColor: isCurrent ? successColor : primaryColor,
223
- title: isCurrent ? 'Current Session' : `Session ${session.sessionId.substring(0, 8)}...`,
225
+ title: isCurrent ? t('sessionManagement.currentSession') : t('sessionManagement.sessionLabel', { id: session.sessionId.substring(0, 8) }),
224
226
  subtitle: subtitleParts.join(' \u2022 '),
225
227
  showChevron: false,
226
228
  multiRow: true,
@@ -234,7 +236,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
234
236
  {switchLoading === session.sessionId ? (
235
237
  <ActivityIndicator size="small" color={primaryColor} />
236
238
  ) : (
237
- <Text style={[styles.sessionPillText, { color: primaryColor }]}>Switch</Text>
239
+ <Text style={[styles.sessionPillText, { color: primaryColor }]}>{t('sessionManagement.switch')}</Text>
238
240
  )}
239
241
  </TouchableOpacity>
240
242
  <TouchableOpacity
@@ -245,13 +247,13 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
245
247
  {actionLoading === session.sessionId ? (
246
248
  <ActivityIndicator size="small" color={dangerColor} />
247
249
  ) : (
248
- <Text style={[styles.sessionPillText, { color: dangerColor }]}>Logout</Text>
250
+ <Text style={[styles.sessionPillText, { color: dangerColor }]}>{t('sessionManagement.logout')}</Text>
249
251
  )}
250
252
  </TouchableOpacity>
251
253
  </View>
252
254
  ) : (
253
255
  <View style={styles.sessionActionsRow}>
254
- <Text style={[styles.currentBadgeText, { color: successColor }]}>Active</Text>
256
+ <Text style={[styles.currentBadgeText, { color: successColor }]}>{t('sessionManagement.active')}</Text>
255
257
  </View>
256
258
  ),
257
259
  selected: isCurrent,
@@ -265,8 +267,8 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
265
267
  id: 'logout-others',
266
268
  icon: 'exit-outline',
267
269
  iconColor: primaryColor,
268
- title: 'Logout Other Sessions',
269
- subtitle: otherSessionsCount === 0 ? 'No other sessions' : 'End all sessions except this one',
270
+ title: t('sessionManagement.logoutOthers.title'),
271
+ subtitle: otherSessionsCount === 0 ? t('sessionManagement.logoutOthers.noOtherSessions') : t('sessionManagement.logoutOthers.subtitle'),
270
272
  onPress: handleLogoutOtherSessions,
271
273
  showChevron: false,
272
274
  customContent: actionLoading === 'others' ? <ActivityIndicator size="small" color={primaryColor} /> : undefined,
@@ -277,8 +279,8 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
277
279
  id: 'logout-all',
278
280
  icon: 'warning-outline',
279
281
  iconColor: dangerColor,
280
- title: 'Logout All Sessions',
281
- subtitle: 'End all sessions including this one',
282
+ title: t('sessionManagement.logoutAll.title'),
283
+ subtitle: t('sessionManagement.logoutAll.subtitle'),
282
284
  onPress: handleLogoutAllSessions,
283
285
  showChevron: false,
284
286
  customContent: actionLoading === 'all' ? <ActivityIndicator size="small" color={dangerColor} /> : undefined,
@@ -291,7 +293,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
291
293
  return (
292
294
  <View style={[styles.container, styles.centerContent, { backgroundColor }]}>
293
295
  <ActivityIndicator size="large" color={primaryColor} />
294
- <Text style={[styles.loadingText, { color: textColor }]}>Loading sessions...</Text>
296
+ <Text style={[styles.loadingText, { color: textColor }]}>{t('sessionManagement.loading')}</Text>
295
297
  </View>
296
298
  );
297
299
  }
@@ -299,8 +301,8 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
299
301
  return (
300
302
  <View style={[styles.container, { backgroundColor }]}>
301
303
  <Header
302
- title="Active Sessions"
303
- subtitle="Manage your active sessions across all devices"
304
+ title={t('sessionManagement.title')}
305
+ subtitle={t('sessionManagement.subtitle')}
304
306
 
305
307
  onBack={goBack || onClose}
306
308
  elevation="subtle"
@@ -319,7 +321,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
319
321
  {userSessions.length > 0 ? (
320
322
  <>
321
323
  {lastRefreshed && (
322
- <Text style={[styles.metaText, { color: '#777', marginBottom: 6 }]}>Last refreshed {formatRelative(lastRefreshed.toISOString())}</Text>
324
+ <Text style={[styles.metaText, { color: '#777', marginBottom: 6 }]}>{t('sessionManagement.lastRefreshed', { time: formatRelative(lastRefreshed.toISOString()) })}</Text>
323
325
  )}
324
326
  <View style={styles.fullBleed}>
325
327
  <GroupedSection items={sessionItems} />
@@ -331,13 +333,13 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
331
333
  </>
332
334
  ) : (
333
335
  <View style={styles.emptyState}>
334
- <Text style={[styles.emptyStateText, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>No active sessions found</Text>
336
+ <Text style={[styles.emptyStateText, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>{t('sessionManagement.empty')}</Text>
335
337
  </View>
336
338
  )}
337
339
  </ScrollView>
338
340
  <View style={[styles.footer, { borderTopColor: borderColor }]}>
339
341
  <TouchableOpacity style={styles.closeButton} onPress={onClose}>
340
- <Text style={[styles.closeButtonText, { color: primaryColor }]}>Close</Text>
342
+ <Text style={[styles.closeButtonText, { color: primaryColor }]}>{t('sessionManagement.close')}</Text>
341
343
  </TouchableOpacity>
342
344
  </View>
343
345
  </View>
@@ -5,6 +5,7 @@ import type { BaseScreenProps } from '../types/navigation';
5
5
  import { Header, GroupedSection } from '../components';
6
6
  import { useThemeStyles } from '../hooks/useThemeStyles';
7
7
  import { normalizeTheme } from '../utils/themeUtils';
8
+ import { useI18n } from '../hooks/useI18n';
8
9
 
9
10
  interface UserLinksScreenProps extends BaseScreenProps {
10
11
  userId: string;
@@ -28,6 +29,7 @@ const UserLinksScreen: React.FC<UserLinksScreenProps> = ({
28
29
  // primaryColor from hook (#007AFF) is already correct for this screen
29
30
  const normalizedTheme = normalizeTheme(theme);
30
31
  const themeStyles = useThemeStyles(normalizedTheme);
32
+ const { t } = useI18n();
31
33
 
32
34
  const handleLinkPress = async (url: string) => {
33
35
  try {
@@ -54,15 +56,15 @@ const UserLinksScreen: React.FC<UserLinksScreenProps> = ({
54
56
  return (
55
57
  <View style={[styles.container, { backgroundColor: themeStyles.backgroundColor }]}>
56
58
  <Header
57
- title="Links"
58
- subtitle={`${links.length} link${links.length !== 1 ? 's' : ''}`}
59
+ title={t('userLinks.title')}
60
+ subtitle={links.length !== 1 ? t('userLinks.linkCount_plural', { count: links.length }) : t('userLinks.linkCount', { count: links.length })}
59
61
  onBack={goBack}
60
62
  elevation="subtle"
61
63
  />
62
64
 
63
65
  <ScrollView style={styles.content}>
64
66
  <View style={styles.section}>
65
- <Text style={[styles.sectionTitle, { color: themeStyles.textColor }]}>Links</Text>
67
+ <Text style={[styles.sectionTitle, { color: themeStyles.textColor }]}>{t('userLinks.title')}</Text>
66
68
 
67
69
  <GroupedSection
68
70
  items={groupedItems}
@@ -164,8 +164,8 @@ const WelcomeNewUserScreen: React.FC<BaseScreenProps & { newUser?: any }> = ({
164
164
  if (avatarStepIndex >= 0 && currentStep !== avatarStepIndex) {
165
165
  animateToStepCallback(avatarStepIndex);
166
166
  }
167
- } catch (e: any) {
168
- toast.error(e.message || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
167
+ } catch (e: unknown) {
168
+ toast.error((e instanceof Error ? e.message : null) || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
169
169
  }
170
170
  }
171
171
  });
@@ -29,7 +29,7 @@ const KarmaLeaderboardScreen: React.FC<BaseScreenProps> = ({ goBack, theme, navi
29
29
  setError(null);
30
30
  oxyServices.getKarmaLeaderboard()
31
31
  .then((data: any) => setLeaderboard(Array.isArray(data) ? data : []))
32
- .catch((err: any) => setError(err.message || 'Failed to load leaderboard'))
32
+ .catch((err: unknown) => setError((err instanceof Error ? err.message : null) || 'Failed to load leaderboard'))
33
33
  .finally(() => setIsLoading(false));
34
34
  }, [oxyServices]);
35
35
 
@@ -28,7 +28,7 @@ const KarmaRulesScreen: React.FC<BaseScreenProps> = ({ goBack, theme }) => {
28
28
  setError(null);
29
29
  oxyServices.getKarmaRules()
30
30
  .then((data: any) => setRules(Array.isArray(data) ? data : []))
31
- .catch((err: any) => setError(err.message || 'Failed to load rules'))
31
+ .catch((err: unknown) => setError((err instanceof Error ? err.message : null) || 'Failed to load rules'))
32
32
  .finally(() => setIsLoading(false));
33
33
  }, [oxyServices]);
34
34
 
@@ -59,10 +59,10 @@ export const useFollowStore = create<FollowState>((set: any, get: any) => ({
59
59
  fetchingUsers: { ...state.fetchingUsers, [userId]: false },
60
60
  errors: { ...state.errors, [userId]: null },
61
61
  }));
62
- } catch (error: any) {
62
+ } catch (error: unknown) {
63
63
  set((state: FollowState) => ({
64
64
  fetchingUsers: { ...state.fetchingUsers, [userId]: false },
65
- errors: { ...state.errors, [userId]: error?.message || 'Failed to fetch follow status' },
65
+ errors: { ...state.errors, [userId]: (error instanceof Error ? error.message : null) || 'Failed to fetch follow status' },
66
66
  }));
67
67
  }
68
68
  },
@@ -119,10 +119,10 @@ export const useFollowStore = create<FollowState>((set: any, get: any) => ({
119
119
  return updates;
120
120
  });
121
121
  }
122
- } catch (error: any) {
122
+ } catch (error: unknown) {
123
123
  set((state: FollowState) => ({
124
124
  loadingUsers: { ...state.loadingUsers, [userId]: false },
125
- errors: { ...state.errors, [userId]: error?.message || 'Failed to update follow status' },
125
+ errors: { ...state.errors, [userId]: (error instanceof Error ? error.message : null) || 'Failed to update follow status' },
126
126
  }));
127
127
  }
128
128
  },
@@ -56,6 +56,8 @@ export interface OxyProviderProps {
56
56
  authWebUrl?: string;
57
57
  authRedirectUri?: string;
58
58
  queryClient?: QueryClient;
59
+ /** Skip wrapping in SafeAreaProvider/GestureHandlerRootView (use when parent already provides them) */
60
+ skipProviderWrappers?: boolean;
59
61
  }
60
62
 
61
63
 
@@ -54,7 +54,7 @@ export const isInvalidSessionError = (error: unknown): boolean => {
54
54
  }
55
55
 
56
56
  // Check error.status directly (HttpService sets this)
57
- if ((error as any).status === 401) {
57
+ if ('status' in (error as object) && (error as Record<string, unknown>).status === 401) {
58
58
  return true;
59
59
  }
60
60
 
@@ -83,7 +83,7 @@ export const isTimeoutOrNetworkError = (error: unknown): boolean => {
83
83
  }
84
84
 
85
85
  const message = extractErrorMessage(error, '').toLowerCase();
86
- const errorCode = (error as any).code;
86
+ const errorCode = isObject(error) && 'code' in (error as object) ? (error as Record<string, unknown>).code : undefined;
87
87
 
88
88
  // Check for timeout/cancelled messages
89
89
  if (
@@ -82,6 +82,7 @@ export async function convertDocumentPickerAssetToFile(
82
82
  }
83
83
  // Preserve URI for preview if available (useful for mobile previews)
84
84
  if (doc.uri) {
85
+ // biome-ignore lint/suspicious/noExplicitAny: attaching uri for mobile preview on a File object requires dynamic property assignment
85
86
  (file as any).uri = doc.uri;
86
87
  }
87
88
  return file;
@@ -102,6 +103,7 @@ export async function convertDocumentPickerAssetToFile(
102
103
  const fileType = doc.mimeType || blob.type || 'application/octet-stream';
103
104
  file = new globalThis.File([blob], fileName, { type: fileType });
104
105
  // Preserve URI for preview
106
+ // biome-ignore lint/suspicious/noExplicitAny: attaching uri for mobile preview on a File object requires dynamic property assignment
105
107
  (file as any).uri = doc.uri;
106
108
  return file;
107
109
  }
@@ -110,7 +112,7 @@ export async function convertDocumentPickerAssetToFile(
110
112
  // React Native's Blob doesn't support Uint8Array directly, so we use fetch
111
113
  const fileName = doc.name || `file-${index + 1}`;
112
114
  const fileType = doc.mimeType || 'application/octet-stream';
113
-
115
+
114
116
  // Use fetch to get the file as a blob (works with file:// and content:// URIs in React Native)
115
117
  const response = await fetch(doc.uri);
116
118
  if (!response.ok) {
@@ -119,17 +121,18 @@ export async function convertDocumentPickerAssetToFile(
119
121
  const blob = await response.blob();
120
122
  file = new globalThis.File([blob], fileName, { type: fileType });
121
123
  // Preserve URI for preview (especially important for mobile)
124
+ // biome-ignore lint/suspicious/noExplicitAny: attaching uri for mobile preview on a File object requires dynamic property assignment
122
125
  (file as any).uri = doc.uri;
123
126
  return file;
124
- } catch (error: any) {
127
+ } catch (error: unknown) {
125
128
  console.error('Failed to read file from URI:', error);
126
- throw new Error(`Failed to load file: ${error.message || 'Unknown error'}`);
129
+ throw new Error(`Failed to load file: ${(error instanceof Error ? error.message : null) || 'Unknown error'}`);
127
130
  }
128
131
  }
129
132
 
130
133
  // No file or URI available - this shouldn't happen with Expo 54
131
134
  throw new Error('Missing file data (no file or uri property)');
132
- } catch (error: any) {
135
+ } catch (error: unknown) {
133
136
  console.error('Error converting document to file:', error);
134
137
  throw error;
135
138
  }
@@ -185,6 +188,7 @@ export function getSafeDownloadUrl(
185
188
  export async function uploadFileRaw(
186
189
  file: File | Blob,
187
190
  userId: string,
191
+ // biome-ignore lint/suspicious/noExplicitAny: OxyServices type cannot be fully resolved due to mixin composition pattern
188
192
  oxyServices: any,
189
193
  visibility?: 'private' | 'public' | 'unlisted'
190
194
  ) {
@@ -198,10 +202,11 @@ export interface AvatarPickerConfig {
198
202
  /** Navigation function from BaseScreenProps */
199
203
  navigate?: (screen: RouteName, props?: Record<string, unknown>) => void;
200
204
  /** OxyServices instance */
205
+ // biome-ignore lint/suspicious/noExplicitAny: OxyServices type cannot be fully resolved due to mixin composition pattern
201
206
  oxyServices: any;
202
207
  /** TanStack Query mutation for updating profile */
203
208
  updateProfileMutation: {
204
- mutateAsync: (updates: { avatar: string }) => Promise<any>;
209
+ mutateAsync: (updates: { avatar: string }) => Promise<unknown>;
205
210
  };
206
211
  /** Callback to update local avatar state */
207
212
  onAvatarSelected?: (fileId: string) => void;
@@ -257,7 +262,7 @@ export function createAvatarPickerHandler(config: AvatarPickerConfig): () => voi
257
262
  multiSelect: false,
258
263
  disabledMimeTypes: ['video/', 'audio/', 'application/pdf'],
259
264
  afterSelect: 'none', // Don't navigate away - stay on current screen
260
- onSelect: async (file: any) => {
265
+ onSelect: async (file: FileMetadata) => {
261
266
  if (!file.contentType.startsWith('image/')) {
262
267
  toast.error(t('editProfile.toasts.selectImage') || 'Please select an image file');
263
268
  return;
@@ -276,8 +281,8 @@ export function createAvatarPickerHandler(config: AvatarPickerConfig): () => voi
276
281
  await updateProfileMutation.mutateAsync({ avatar: file.id });
277
282
 
278
283
  toast.success(t('editProfile.toasts.avatarUpdated') || 'Avatar updated');
279
- } catch (e: any) {
280
- toast.error(e.message || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
284
+ } catch (e: unknown) {
285
+ toast.error((e instanceof Error ? e.message : null) || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
281
286
  }
282
287
  }
283
288
  });
@@ -13,10 +13,11 @@ interface DeviceSession {
13
13
 
14
14
  /**
15
15
  * Service type for session helpers.
16
- * Uses 'any' to work around TypeScript mixin composition type inference issues.
16
+ * Uses 'unknown' to work around TypeScript mixin composition type inference issues.
17
17
  * The OxyServices class has these methods but TypeScript can't see them due to the mixin pattern.
18
+ * Methods are accessed dynamically, so callers must pass a properly typed instance.
18
19
  */
19
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ // biome-ignore lint/suspicious/noExplicitAny: OxyServices methods are accessed dynamically due to mixin composition; TypeScript cannot infer the full type
20
21
  type OxyServicesAny = any;
21
22
 
22
23
  export interface FetchSessionsWithFallbackOptions {