@oxyhq/services 5.5.9 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/README.md +16 -2
  2. package/lib/commonjs/core/index.js +69 -82
  3. package/lib/commonjs/core/index.js.map +1 -1
  4. package/lib/commonjs/index.js +24 -183
  5. package/lib/commonjs/index.js.map +1 -1
  6. package/lib/commonjs/node/index.js +0 -2
  7. package/lib/commonjs/node/index.js.map +1 -1
  8. package/lib/commonjs/ui/components/FollowButton.js +100 -229
  9. package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
  10. package/lib/commonjs/ui/components/OxyPayButton.js +131 -0
  11. package/lib/commonjs/ui/components/OxyPayButton.js.map +1 -0
  12. package/lib/commonjs/ui/components/OxyProvider.js +41 -198
  13. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  14. package/lib/commonjs/ui/components/OxySignInButton.js +15 -2
  15. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
  16. package/lib/commonjs/ui/components/icon/FAIRWalletIcon.js +66 -0
  17. package/lib/commonjs/ui/components/icon/FAIRWalletIcon.js.map +1 -0
  18. package/lib/commonjs/ui/components/icon/index.js +7 -0
  19. package/lib/commonjs/ui/components/icon/index.js.map +1 -1
  20. package/lib/commonjs/ui/components/index.js +7 -0
  21. package/lib/commonjs/ui/components/index.js.map +1 -1
  22. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +14 -7
  23. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
  24. package/lib/commonjs/ui/components/internal/PinInput.js +108 -0
  25. package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -0
  26. package/lib/commonjs/ui/components/internal/TextField.js +20 -0
  27. package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
  28. package/lib/commonjs/ui/context/OxyContext.js +26 -36
  29. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  30. package/lib/commonjs/ui/hooks/index.js +2 -15
  31. package/lib/commonjs/ui/hooks/index.js.map +1 -1
  32. package/lib/commonjs/ui/hooks/useFollow.js +52 -136
  33. package/lib/commonjs/ui/hooks/useFollow.js.map +1 -1
  34. package/lib/commonjs/ui/hooks/useSessionSocket.js +52 -0
  35. package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -0
  36. package/lib/commonjs/ui/index.js +8 -191
  37. package/lib/commonjs/ui/index.js.map +1 -1
  38. package/lib/commonjs/ui/navigation/OxyRouter.js +52 -60
  39. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  40. package/lib/commonjs/ui/screens/AccountCenterScreen.js +18 -30
  41. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  42. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +4 -22
  43. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  44. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +6 -14
  45. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  46. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +37 -66
  47. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  48. package/lib/commonjs/ui/screens/AppInfoScreen.js +21 -44
  49. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  50. package/lib/commonjs/ui/screens/FeedbackScreen.js +44 -23
  51. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  52. package/lib/commonjs/ui/screens/FileManagementScreen.js +59 -78
  53. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  54. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +1588 -0
  55. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -0
  56. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +22 -36
  57. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  58. package/lib/commonjs/ui/screens/RecoverAccountScreen.js +269 -0
  59. package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -0
  60. package/lib/commonjs/ui/screens/SessionManagementScreen.js +47 -69
  61. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  62. package/lib/commonjs/ui/screens/SignInScreen.js +99 -333
  63. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  64. package/lib/commonjs/ui/screens/SignUpScreen.js +136 -340
  65. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  66. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +192 -0
  67. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -0
  68. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +135 -0
  69. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -0
  70. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +108 -0
  71. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +1 -0
  72. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +126 -0
  73. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +1 -0
  74. package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js +84 -0
  75. package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js.map +1 -0
  76. package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js +59 -0
  77. package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js.map +1 -0
  78. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +15 -2
  79. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  80. package/lib/commonjs/ui/stores/authStore.js +31 -0
  81. package/lib/commonjs/ui/stores/authStore.js.map +1 -0
  82. package/lib/commonjs/ui/stores/followStore.js +124 -0
  83. package/lib/commonjs/ui/stores/followStore.js.map +1 -0
  84. package/lib/commonjs/ui/styles/index.js +0 -11
  85. package/lib/commonjs/ui/styles/index.js.map +1 -1
  86. package/lib/commonjs/ui/utils/confirmAction.js +28 -0
  87. package/lib/commonjs/ui/utils/confirmAction.js.map +1 -0
  88. package/lib/module/core/index.js +69 -81
  89. package/lib/module/core/index.js.map +1 -1
  90. package/lib/module/index.js +14 -17
  91. package/lib/module/index.js.map +1 -1
  92. package/lib/module/node/index.js +0 -3
  93. package/lib/module/node/index.js.map +1 -1
  94. package/lib/module/ui/components/FollowButton.js +100 -229
  95. package/lib/module/ui/components/FollowButton.js.map +1 -1
  96. package/lib/module/ui/components/OxyPayButton.js +125 -0
  97. package/lib/module/ui/components/OxyPayButton.js.map +1 -0
  98. package/lib/module/ui/components/OxyProvider.js +42 -199
  99. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  100. package/lib/module/ui/components/OxySignInButton.js +15 -2
  101. package/lib/module/ui/components/OxySignInButton.js.map +1 -1
  102. package/lib/module/ui/components/icon/FAIRWalletIcon.js +60 -0
  103. package/lib/module/ui/components/icon/FAIRWalletIcon.js.map +1 -0
  104. package/lib/module/ui/components/icon/index.js +1 -0
  105. package/lib/module/ui/components/icon/index.js.map +1 -1
  106. package/lib/module/ui/components/index.js +1 -0
  107. package/lib/module/ui/components/index.js.map +1 -1
  108. package/lib/module/ui/components/internal/GroupedPillButtons.js +15 -8
  109. package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
  110. package/lib/module/ui/components/internal/PinInput.js +103 -0
  111. package/lib/module/ui/components/internal/PinInput.js.map +1 -0
  112. package/lib/module/ui/components/internal/TextField.js +20 -0
  113. package/lib/module/ui/components/internal/TextField.js.map +1 -1
  114. package/lib/module/ui/context/OxyContext.js +26 -36
  115. package/lib/module/ui/context/OxyContext.js.map +1 -1
  116. package/lib/module/ui/hooks/index.js +1 -2
  117. package/lib/module/ui/hooks/index.js.map +1 -1
  118. package/lib/module/ui/hooks/useFollow.js +52 -137
  119. package/lib/module/ui/hooks/useFollow.js.map +1 -1
  120. package/lib/module/ui/hooks/useSessionSocket.js +47 -0
  121. package/lib/module/ui/hooks/useSessionSocket.js.map +1 -0
  122. package/lib/module/ui/index.js +2 -13
  123. package/lib/module/ui/index.js.map +1 -1
  124. package/lib/module/ui/navigation/OxyRouter.js +53 -61
  125. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  126. package/lib/module/ui/screens/AccountCenterScreen.js +6 -18
  127. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  128. package/lib/module/ui/screens/AccountOverviewScreen.js +5 -23
  129. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  130. package/lib/module/ui/screens/AccountSettingsScreen.js +7 -15
  131. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  132. package/lib/module/ui/screens/AccountSwitcherScreen.js +38 -67
  133. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  134. package/lib/module/ui/screens/AppInfoScreen.js +22 -45
  135. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  136. package/lib/module/ui/screens/FeedbackScreen.js +44 -23
  137. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  138. package/lib/module/ui/screens/FileManagementScreen.js +59 -78
  139. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  140. package/lib/module/ui/screens/PaymentGatewayScreen.js +1583 -0
  141. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -0
  142. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +23 -37
  143. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  144. package/lib/module/ui/screens/RecoverAccountScreen.js +263 -0
  145. package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -0
  146. package/lib/module/ui/screens/SessionManagementScreen.js +47 -69
  147. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  148. package/lib/module/ui/screens/SignInScreen.js +100 -334
  149. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  150. package/lib/module/ui/screens/SignUpScreen.js +137 -341
  151. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  152. package/lib/module/ui/screens/internal/SignInPasswordStep.js +186 -0
  153. package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -0
  154. package/lib/module/ui/screens/internal/SignInUsernameStep.js +129 -0
  155. package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -0
  156. package/lib/module/ui/screens/internal/SignUpIdentityStep.js +102 -0
  157. package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +1 -0
  158. package/lib/module/ui/screens/internal/SignUpSecurityStep.js +120 -0
  159. package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +1 -0
  160. package/lib/module/ui/screens/internal/SignUpSummaryStep.js +79 -0
  161. package/lib/module/ui/screens/internal/SignUpSummaryStep.js.map +1 -0
  162. package/lib/module/ui/screens/internal/SignUpWelcomeStep.js +54 -0
  163. package/lib/module/ui/screens/internal/SignUpWelcomeStep.js.map +1 -0
  164. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +16 -3
  165. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  166. package/lib/module/ui/stores/authStore.js +27 -0
  167. package/lib/module/ui/stores/authStore.js.map +1 -0
  168. package/lib/module/ui/stores/followStore.js +120 -0
  169. package/lib/module/ui/stores/followStore.js.map +1 -0
  170. package/lib/module/ui/styles/index.js +0 -1
  171. package/lib/module/ui/styles/index.js.map +1 -1
  172. package/lib/module/ui/utils/confirmAction.js +25 -0
  173. package/lib/module/ui/utils/confirmAction.js.map +1 -0
  174. package/lib/typescript/core/index.d.ts +28 -10
  175. package/lib/typescript/core/index.d.ts.map +1 -1
  176. package/lib/typescript/index.d.ts +5 -4
  177. package/lib/typescript/index.d.ts.map +1 -1
  178. package/lib/typescript/models/secureSession.d.ts +0 -1
  179. package/lib/typescript/models/secureSession.d.ts.map +1 -1
  180. package/lib/typescript/node/index.d.ts +0 -1
  181. package/lib/typescript/node/index.d.ts.map +1 -1
  182. package/lib/typescript/ui/components/FollowButton.d.ts +1 -77
  183. package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
  184. package/lib/typescript/ui/components/OxyPayButton.d.ts +29 -0
  185. package/lib/typescript/ui/components/OxyPayButton.d.ts.map +1 -0
  186. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  187. package/lib/typescript/ui/components/OxySignInButton.d.ts.map +1 -1
  188. package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts +8 -0
  189. package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts.map +1 -0
  190. package/lib/typescript/ui/components/icon/index.d.ts +1 -0
  191. package/lib/typescript/ui/components/icon/index.d.ts.map +1 -1
  192. package/lib/typescript/ui/components/index.d.ts +1 -0
  193. package/lib/typescript/ui/components/index.d.ts.map +1 -1
  194. package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
  195. package/lib/typescript/ui/components/internal/PinInput.d.ts +12 -0
  196. package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -0
  197. package/lib/typescript/ui/components/internal/TextField.d.ts +1 -0
  198. package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
  199. package/lib/typescript/ui/context/OxyContext.d.ts +0 -2
  200. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  201. package/lib/typescript/ui/hooks/index.d.ts +1 -2
  202. package/lib/typescript/ui/hooks/index.d.ts.map +1 -1
  203. package/lib/typescript/ui/hooks/useFollow.d.ts +14 -15
  204. package/lib/typescript/ui/hooks/useFollow.d.ts.map +1 -1
  205. package/lib/typescript/ui/hooks/useSessionSocket.d.ts +11 -0
  206. package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -0
  207. package/lib/typescript/ui/index.d.ts +2 -5
  208. package/lib/typescript/ui/index.d.ts.map +1 -1
  209. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
  210. package/lib/typescript/ui/navigation/types.d.ts +5 -23
  211. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  212. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  213. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  214. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  215. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  216. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
  217. package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
  218. package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
  219. package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts +27 -0
  220. package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -0
  221. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
  222. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +8 -0
  223. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -0
  224. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  225. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  226. package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
  227. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +27 -0
  228. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -0
  229. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +26 -0
  230. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -0
  231. package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts +20 -0
  232. package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +1 -0
  233. package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts +24 -0
  234. package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +1 -0
  235. package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts +15 -0
  236. package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts.map +1 -0
  237. package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts +13 -0
  238. package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts.map +1 -0
  239. package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
  240. package/lib/typescript/ui/stores/authStore.d.ts +14 -0
  241. package/lib/typescript/ui/stores/authStore.d.ts.map +1 -0
  242. package/lib/typescript/ui/stores/followStore.d.ts +15 -0
  243. package/lib/typescript/ui/stores/followStore.d.ts.map +1 -0
  244. package/lib/typescript/ui/styles/index.d.ts +0 -1
  245. package/lib/typescript/ui/styles/index.d.ts.map +1 -1
  246. package/lib/typescript/ui/utils/confirmAction.d.ts +7 -0
  247. package/lib/typescript/ui/utils/confirmAction.d.ts.map +1 -0
  248. package/package.json +12 -7
  249. package/src/core/index.ts +78 -88
  250. package/src/index.ts +8 -45
  251. package/src/models/secureSession.ts +1 -2
  252. package/src/node/index.ts +0 -3
  253. package/src/ui/components/FollowButton.tsx +100 -322
  254. package/src/ui/components/OxyPayButton.tsx +133 -0
  255. package/src/ui/components/OxyProvider.tsx +39 -201
  256. package/src/ui/components/OxySignInButton.tsx +13 -2
  257. package/src/ui/components/icon/FAIRWalletIcon.tsx +49 -0
  258. package/src/ui/components/icon/index.ts +1 -0
  259. package/src/ui/components/index.ts +1 -0
  260. package/src/ui/components/internal/GroupedPillButtons.tsx +12 -8
  261. package/src/ui/components/internal/PinInput.tsx +102 -0
  262. package/src/ui/components/internal/TextField.tsx +9 -0
  263. package/src/ui/context/OxyContext.tsx +26 -40
  264. package/src/ui/hooks/index.ts +1 -2
  265. package/src/ui/hooks/useFollow.ts +58 -129
  266. package/src/ui/hooks/useSessionSocket.ts +50 -0
  267. package/src/ui/index.ts +2 -37
  268. package/src/ui/navigation/OxyRouter.tsx +47 -63
  269. package/src/ui/navigation/types.ts +5 -26
  270. package/src/ui/screens/AccountCenterScreen.tsx +12 -21
  271. package/src/ui/screens/AccountOverviewScreen.tsx +6 -30
  272. package/src/ui/screens/AccountSettingsScreen.tsx +7 -22
  273. package/src/ui/screens/AccountSwitcherScreen.tsx +46 -88
  274. package/src/ui/screens/AppInfoScreen.tsx +27 -47
  275. package/src/ui/screens/FeedbackScreen.tsx +34 -19
  276. package/src/ui/screens/FileManagementScreen.tsx +293 -321
  277. package/src/ui/screens/PaymentGatewayScreen.tsx +1315 -0
  278. package/src/ui/screens/PremiumSubscriptionScreen.tsx +109 -124
  279. package/src/ui/screens/RecoverAccountScreen.tsx +260 -0
  280. package/src/ui/screens/SessionManagementScreen.tsx +65 -137
  281. package/src/ui/screens/SignInScreen.tsx +89 -283
  282. package/src/ui/screens/SignUpScreen.tsx +138 -291
  283. package/src/ui/screens/internal/SignInPasswordStep.tsx +179 -0
  284. package/src/ui/screens/internal/SignInUsernameStep.tsx +139 -0
  285. package/src/ui/screens/internal/SignUpIdentityStep.tsx +114 -0
  286. package/src/ui/screens/internal/SignUpSecurityStep.tsx +132 -0
  287. package/src/ui/screens/internal/SignUpSummaryStep.tsx +66 -0
  288. package/src/ui/screens/internal/SignUpWelcomeStep.tsx +52 -0
  289. package/src/ui/screens/karma/KarmaRewardsScreen.tsx +13 -3
  290. package/src/ui/stores/authStore.ts +24 -0
  291. package/src/ui/stores/followStore.ts +80 -0
  292. package/src/ui/styles/index.ts +0 -1
  293. package/src/ui/utils/confirmAction.ts +23 -0
  294. package/lib/commonjs/ui/components/bottomSheet/index.js +0 -37
  295. package/lib/commonjs/ui/components/bottomSheet/index.js.map +0 -1
  296. package/lib/commonjs/ui/hooks/useAuthFetch.js +0 -217
  297. package/lib/commonjs/ui/hooks/useAuthFetch.js.map +0 -1
  298. package/lib/commonjs/ui/hooks/useOxyFollow.js +0 -190
  299. package/lib/commonjs/ui/hooks/useOxyFollow.js.map +0 -1
  300. package/lib/commonjs/ui/screens/BillingManagementScreen.js +0 -636
  301. package/lib/commonjs/ui/screens/BillingManagementScreen.js.map +0 -1
  302. package/lib/commonjs/ui/store/index.js +0 -67
  303. package/lib/commonjs/ui/store/index.js.map +0 -1
  304. package/lib/commonjs/ui/store/setupOxyStore.js +0 -63
  305. package/lib/commonjs/ui/store/setupOxyStore.js.map +0 -1
  306. package/lib/commonjs/ui/store/slices/authSlice.js +0 -56
  307. package/lib/commonjs/ui/store/slices/authSlice.js.map +0 -1
  308. package/lib/commonjs/ui/store/slices/followSlice.js +0 -238
  309. package/lib/commonjs/ui/store/slices/followSlice.js.map +0 -1
  310. package/lib/commonjs/ui/store/slices/index.js +0 -129
  311. package/lib/commonjs/ui/store/slices/index.js.map +0 -1
  312. package/lib/commonjs/ui/store/slices/types.js +0 -19
  313. package/lib/commonjs/ui/store/slices/types.js.map +0 -1
  314. package/lib/commonjs/ui/styles/shadows.js +0 -123
  315. package/lib/commonjs/ui/styles/shadows.js.map +0 -1
  316. package/lib/commonjs/utils/polyfills.js +0 -42
  317. package/lib/commonjs/utils/polyfills.js.map +0 -1
  318. package/lib/module/ui/components/bottomSheet/index.js +0 -5
  319. package/lib/module/ui/components/bottomSheet/index.js.map +0 -1
  320. package/lib/module/ui/hooks/useAuthFetch.js +0 -212
  321. package/lib/module/ui/hooks/useAuthFetch.js.map +0 -1
  322. package/lib/module/ui/hooks/useOxyFollow.js +0 -186
  323. package/lib/module/ui/hooks/useOxyFollow.js.map +0 -1
  324. package/lib/module/ui/screens/BillingManagementScreen.js +0 -631
  325. package/lib/module/ui/screens/BillingManagementScreen.js.map +0 -1
  326. package/lib/module/ui/store/index.js +0 -33
  327. package/lib/module/ui/store/index.js.map +0 -1
  328. package/lib/module/ui/store/setupOxyStore.js +0 -59
  329. package/lib/module/ui/store/setupOxyStore.js.map +0 -1
  330. package/lib/module/ui/store/slices/authSlice.js +0 -48
  331. package/lib/module/ui/store/slices/authSlice.js.map +0 -1
  332. package/lib/module/ui/store/slices/followSlice.js +0 -232
  333. package/lib/module/ui/store/slices/followSlice.js.map +0 -1
  334. package/lib/module/ui/store/slices/index.js +0 -11
  335. package/lib/module/ui/store/slices/index.js.map +0 -1
  336. package/lib/module/ui/store/slices/types.js +0 -15
  337. package/lib/module/ui/store/slices/types.js.map +0 -1
  338. package/lib/module/ui/styles/shadows.js +0 -119
  339. package/lib/module/ui/styles/shadows.js.map +0 -1
  340. package/lib/module/utils/polyfills.js +0 -36
  341. package/lib/module/utils/polyfills.js.map +0 -1
  342. package/lib/typescript/types/react-redux.d.ts +0 -5
  343. package/lib/typescript/ui/components/bottomSheet/index.d.ts +0 -4
  344. package/lib/typescript/ui/components/bottomSheet/index.d.ts.map +0 -1
  345. package/lib/typescript/ui/hooks/useAuthFetch.d.ts +0 -34
  346. package/lib/typescript/ui/hooks/useAuthFetch.d.ts.map +0 -1
  347. package/lib/typescript/ui/hooks/useOxyFollow.d.ts +0 -81
  348. package/lib/typescript/ui/hooks/useOxyFollow.d.ts.map +0 -1
  349. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts +0 -5
  350. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts.map +0 -1
  351. package/lib/typescript/ui/store/index.d.ts +0 -27
  352. package/lib/typescript/ui/store/index.d.ts.map +0 -1
  353. package/lib/typescript/ui/store/setupOxyStore.d.ts +0 -29
  354. package/lib/typescript/ui/store/setupOxyStore.d.ts.map +0 -1
  355. package/lib/typescript/ui/store/slices/authSlice.d.ts +0 -32
  356. package/lib/typescript/ui/store/slices/authSlice.d.ts.map +0 -1
  357. package/lib/typescript/ui/store/slices/followSlice.d.ts +0 -120
  358. package/lib/typescript/ui/store/slices/followSlice.d.ts.map +0 -1
  359. package/lib/typescript/ui/store/slices/index.d.ts +0 -9
  360. package/lib/typescript/ui/store/slices/index.d.ts.map +0 -1
  361. package/lib/typescript/ui/store/slices/types.d.ts +0 -16
  362. package/lib/typescript/ui/store/slices/types.d.ts.map +0 -1
  363. package/lib/typescript/ui/styles/shadows.d.ts +0 -233
  364. package/lib/typescript/ui/styles/shadows.d.ts.map +0 -1
  365. package/lib/typescript/utils/polyfills.d.ts +0 -6
  366. package/lib/typescript/utils/polyfills.d.ts.map +0 -1
  367. package/src/__tests__/backend-middleware.test.ts +0 -209
  368. package/src/__tests__/polyfills.test.ts +0 -30
  369. package/src/__tests__/setup.ts +0 -43
  370. package/src/__tests__/ui/hooks/authfetch-integration.test.ts +0 -197
  371. package/src/__tests__/ui/hooks/backward-compatibility.test.ts +0 -159
  372. package/src/__tests__/ui/hooks/real-world-scenarios.test.ts +0 -224
  373. package/src/__tests__/ui/hooks/url-resolution.test.ts +0 -129
  374. package/src/__tests__/ui/hooks/useAuthFetch-separation.test.ts +0 -69
  375. package/src/__tests__/ui/hooks/useAuthFetch.test.ts +0 -70
  376. package/src/__tests__/ui/hooks/useOxyFollow.test.tsx +0 -92
  377. package/src/__tests__/ui/screens/AccountSettingsScreen.test.tsx +0 -112
  378. package/src/__tests__/ui/store/setupOxyStore.test.ts +0 -50
  379. package/src/__tests__/validate-structure.js +0 -91
  380. package/src/__tests__/validation.js +0 -42
  381. package/src/types/react-redux.d.ts +0 -5
  382. package/src/ui/components/bottomSheet/index.tsx +0 -14
  383. package/src/ui/hooks/useAuthFetch.ts +0 -238
  384. package/src/ui/hooks/useOxyFollow.ts +0 -188
  385. package/src/ui/screens/BillingManagementScreen.tsx +0 -589
  386. package/src/ui/store/index.ts +0 -36
  387. package/src/ui/store/setupOxyStore.ts +0 -58
  388. package/src/ui/store/slices/authSlice.ts +0 -43
  389. package/src/ui/store/slices/followSlice.ts +0 -207
  390. package/src/ui/store/slices/index.ts +0 -31
  391. package/src/ui/store/slices/types.ts +0 -33
  392. package/src/ui/styles/shadows.ts +0 -112
  393. package/src/utils/polyfills.ts +0 -34
@@ -0,0 +1,102 @@
1
+ import React, { useRef } from 'react';
2
+ import { View, TextInput, StyleSheet, Platform } from 'react-native';
3
+
4
+ interface PinInputProps {
5
+ value: string;
6
+ onChange: (val: string) => void;
7
+ length?: number;
8
+ disabled?: boolean;
9
+ autoFocus?: boolean;
10
+ colors: any;
11
+ }
12
+
13
+ const PinInput: React.FC<PinInputProps> = ({ value, onChange, length = 6, disabled, autoFocus, colors }) => {
14
+ const inputs = useRef<Array<TextInput | null>>([]);
15
+
16
+ const handleChange = (text: string, idx: number) => {
17
+ if (!/^[0-9]*$/.test(text)) return;
18
+ let newValue = value.split('');
19
+ if (text.length > 1) {
20
+ // Paste or autofill
21
+ newValue = text.split('').slice(0, length);
22
+ onChange(newValue.join(''));
23
+ if (newValue.length < length) {
24
+ inputs.current[newValue.length]?.focus();
25
+ }
26
+ return;
27
+ }
28
+ newValue[idx] = text;
29
+ const joined = newValue.join('').slice(0, length);
30
+ onChange(joined);
31
+ if (text && idx < length - 1) {
32
+ inputs.current[idx + 1]?.focus();
33
+ }
34
+ };
35
+
36
+ const handleKeyPress = (e: any, idx: number) => {
37
+ if (e.nativeEvent.key === 'Backspace' && !value[idx] && idx > 0) {
38
+ inputs.current[idx - 1]?.focus();
39
+ }
40
+ };
41
+
42
+ return (
43
+ <View style={styles.pinContainer}>
44
+ {Array.from({ length }).map((_, idx) => (
45
+ <TextInput
46
+ key={idx}
47
+ ref={ref => (inputs.current[idx] = ref)}
48
+ style={[
49
+ styles.pinInput,
50
+ { borderColor: colors.primary, color: colors.text, backgroundColor: colors.inputBackground },
51
+ value[idx] ? { borderWidth: 2 } : { borderWidth: 1 },
52
+ ]}
53
+ value={value[idx] || ''}
54
+ onChangeText={text => handleChange(text, idx)}
55
+ onKeyPress={e => handleKeyPress(e, idx)}
56
+ keyboardType={Platform.OS === 'ios' ? 'number-pad' : 'numeric'}
57
+ maxLength={1}
58
+ editable={!disabled}
59
+ autoFocus={autoFocus && idx === 0}
60
+ textAlign="center"
61
+ selectionColor={colors.primary}
62
+ returnKeyType="done"
63
+ />
64
+ ))}
65
+ </View>
66
+ );
67
+ };
68
+
69
+ const styles = StyleSheet.create({
70
+ pinContainer: {
71
+ flexDirection: 'row',
72
+ justifyContent: 'center',
73
+ gap: 12,
74
+ marginBottom: 24,
75
+ marginTop: 8,
76
+ },
77
+ pinInput: {
78
+ width: 44,
79
+ height: 54,
80
+ borderRadius: 12,
81
+ borderWidth: 1,
82
+ fontSize: 28,
83
+ fontWeight: '600',
84
+ backgroundColor: '#F5F5F5',
85
+ textAlign: 'center',
86
+ marginHorizontal: 2,
87
+ ...Platform.select({
88
+ web: {
89
+ boxShadow: '0 1px 4px rgba(0,0,0,0.04)',
90
+ },
91
+ default: {
92
+ shadowColor: '#000',
93
+ shadowOpacity: 0.04,
94
+ shadowOffset: { width: 0, height: 1 },
95
+ shadowRadius: 4,
96
+ elevation: 1,
97
+ }
98
+ }),
99
+ },
100
+ });
101
+
102
+ export default PinInput;
@@ -34,6 +34,7 @@ export interface TextFieldProps extends Omit<TextInputProps, 'style'> {
34
34
  onBlur?: () => void;
35
35
  onChangeText?: (text: string) => void;
36
36
  testID?: string;
37
+ validMessage?: string;
37
38
  }
38
39
 
39
40
  const TextField = forwardRef<TextInput, TextFieldProps>(({
@@ -57,6 +58,7 @@ const TextField = forwardRef<TextInput, TextFieldProps>(({
57
58
  testID,
58
59
  secureTextEntry,
59
60
  value = '',
61
+ validMessage,
60
62
  ...textInputProps
61
63
  }, ref) => {
62
64
  const [isFocused, setIsFocused] = useState(false);
@@ -556,6 +558,13 @@ const TextField = forwardRef<TextInput, TextFieldProps>(({
556
558
  </Text>
557
559
  </View>
558
560
  )}
561
+ {/* Valid Message */}
562
+ {!error && validMessage && (
563
+ <View style={{ flexDirection: 'row', alignItems: 'center', marginTop: 4, gap: 6 }}>
564
+ <Ionicons name="checkmark-circle" size={16} color={colors?.success || '#2E7D32'} />
565
+ <Text style={{ fontSize: 13, fontWeight: '500', color: colors?.success || '#2E7D32' }}>{validMessage}</Text>
566
+ </View>
567
+ )}
559
568
  </View>
560
569
  );
561
570
  });
@@ -3,6 +3,8 @@ import { OxyServices } from '../../core';
3
3
  import { User } from '../../models/interfaces';
4
4
  import { SecureLoginResponse, SecureClientSession, MinimalUserData } from '../../models/secureSession';
5
5
  import { DeviceManager } from '../../utils/deviceManager';
6
+ import { useSessionSocket } from '../hooks/useSessionSocket';
7
+ import { toast } from '../../lib/sonner';
6
8
 
7
9
  // Define the context shape
8
10
  export interface OxyContextState {
@@ -35,10 +37,6 @@ export interface OxyContextState {
35
37
  oxyServices: OxyServices;
36
38
  bottomSheetRef?: React.RefObject<any>;
37
39
 
38
- // API configuration
39
- setApiUrl: (url: string) => void;
40
- getAppBaseURL: () => string;
41
-
42
40
  // Methods to directly control the bottom sheet
43
41
  showBottomSheet?: (screenOrConfig?: string | { screen: string; props?: Record<string, any> }) => void;
44
42
  hideBottomSheet?: () => void;
@@ -130,7 +128,6 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
130
128
  const [isLoading, setIsLoading] = useState(true);
131
129
  const [error, setError] = useState<string | null>(null);
132
130
  const [storage, setStorage] = useState<StorageInterface | null>(null);
133
- const [appBaseURL, setAppBaseURL] = useState<string>(oxyServices.getBaseURL());
134
131
 
135
132
  // Storage keys (memoized to prevent infinite loops)
136
133
  const keys = useMemo(() => getSecureStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
@@ -172,17 +169,16 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
172
169
  let shouldUpdateStorage = false;
173
170
 
174
171
  for (const session of parsedSessions) {
175
- if (!session.userId || !session.username) {
172
+ if (!session.userId) {
176
173
  // Session is missing user info, try to fetch it
177
174
  try {
178
175
  const sessionUser = await oxyServices.getUserBySession(session.sessionId);
179
176
  migratedSessions.push({
180
177
  ...session,
181
- userId: sessionUser.id,
182
- username: sessionUser.username
178
+ userId: sessionUser.id
183
179
  });
184
180
  shouldUpdateStorage = true;
185
- console.log(`Migrated session ${session.sessionId} for user ${sessionUser.username}`);
181
+ console.log(`Migrated session ${session.sessionId} for user ${sessionUser.id}`);
186
182
  } catch (error) {
187
183
  // Session might be invalid, skip it
188
184
  console.log(`Removing invalid session ${session.sessionId}:`, error);
@@ -361,13 +357,12 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
361
357
  deviceId: response.deviceId,
362
358
  expiresAt: response.expiresAt,
363
359
  lastActive: new Date().toISOString(),
364
- userId: response.user.id,
365
- username: response.user.username
360
+ userId: response.user.id
366
361
  };
367
362
 
368
363
  // Check if this user already has a session (prevent duplicate accounts)
369
364
  const existingUserSessionIndex = sessions.findIndex(s =>
370
- s.userId === response.user.id || s.username === response.user.username
365
+ s.userId === response.user.id
371
366
  );
372
367
 
373
368
  let updatedSessions: SecureClientSession[];
@@ -378,7 +373,7 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
378
373
  updatedSessions = [...sessions];
379
374
  updatedSessions[existingUserSessionIndex] = clientSession;
380
375
 
381
- console.log(`Reusing/updating existing session for user ${response.user.username}. Previous session: ${existingSession.sessionId}, New session: ${response.sessionId}`);
376
+ console.log(`Reusing/updating existing session for user ${response.user.id}. Previous session: ${existingSession.sessionId}, New session: ${response.sessionId}`);
382
377
 
383
378
  // If the replaced session was the active one, update active session
384
379
  if (activeSessionId === existingSession.sessionId) {
@@ -388,7 +383,7 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
388
383
  } else {
389
384
  // Add new session for new user
390
385
  updatedSessions = [...sessions, clientSession];
391
- console.log(`Added new session for user ${response.user.username} on device ${response.deviceId}`);
386
+ console.log(`Added new session for user ${response.user.id} on device ${response.deviceId}`);
392
387
  }
393
388
 
394
389
  setSessions(updatedSessions);
@@ -645,36 +640,29 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
645
640
  }
646
641
  }, [bottomSheetRef]);
647
642
 
648
- // API URL configuration
649
- const setApiUrl = useCallback((url: string) => {
650
- try {
651
- // Validate URL
652
- if (!url) {
653
- throw new Error('Base URL cannot be empty');
654
- }
655
- // Only update the app-specific base URL, not the OxyServices base URL
656
- // This ensures internal module calls to Oxy API remain unaffected
657
- setAppBaseURL(url);
658
- } catch (error) {
659
- console.error('Failed to update API URL:', error);
660
- setError(`Failed to update API URL: ${error instanceof Error ? error.message : 'Unknown error'}`);
661
- }
662
- }, []);
663
-
664
- // Get current app base URL
665
- const getAppBaseURL = useCallback(() => {
666
- return appBaseURL;
667
- }, [appBaseURL]);
668
-
669
643
  // Compute comprehensive authentication status
670
644
  // This is the single source of truth for authentication across the entire app
671
645
  const isAuthenticated = useMemo(() => {
672
646
  // User is authenticated if:
673
647
  // 1. We have a full user object loaded, OR
674
- // 2. We have an active session (token will be fetched on-demand)
648
+ // 2. We have an active session with a valid token
675
649
  // This covers both the loaded state and the loading-but-authenticated state
676
- return !!user || !!activeSessionId;
677
- }, [user, activeSessionId]);
650
+ return !!user || (!!activeSessionId && !!oxyServices?.getCurrentUserId());
651
+ }, [user, activeSessionId, oxyServices]);
652
+
653
+ // Integrate socket for real-time session updates
654
+ console.log('OxyContextProvider: userId', user?.id, 'baseURL', oxyServices.getBaseURL());
655
+ useSessionSocket({
656
+ userId: user?.id,
657
+ activeSessionId,
658
+ refreshSessions,
659
+ logout: () => logout(),
660
+ baseURL: oxyServices.getBaseURL(),
661
+ onRemoteSignOut: () => {
662
+ toast.info('You have been signed out remotely.');
663
+ logout();
664
+ },
665
+ });
678
666
 
679
667
  // Context value
680
668
  const contextValue: OxyContextState = {
@@ -696,8 +684,6 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
696
684
  logoutAllDeviceSessions,
697
685
  updateDeviceName,
698
686
  oxyServices,
699
- setApiUrl,
700
- getAppBaseURL,
701
687
  bottomSheetRef,
702
688
  showBottomSheet,
703
689
  hideBottomSheet,
@@ -1,2 +1 @@
1
- export { useOxyFollow, useFollow } from './useOxyFollow';
2
- export { useAuthFetch } from './useAuthFetch';
1
+ export { useFollow } from './useFollow';
@@ -1,173 +1,102 @@
1
- import { useDispatch, useSelector } from 'react-redux';
2
1
  import { useCallback, useMemo } from 'react';
3
- import { toggleFollowUser, setFollowingStatus, clearFollowError, fetchFollowStatus } from '../store';
4
- import type { RootState } from '../store';
2
+ import { useFollowStore } from '../stores/followStore';
5
3
  import { useOxy } from '../context/OxyContext';
6
4
 
7
- // Memoized selector to prevent unnecessary re-renders
8
- const createFollowSelector = (userId: string) => (state: RootState) => ({
9
- isFollowing: state.follow.followingUsers[userId] ?? false,
10
- isLoading: state.follow.loadingUsers[userId] ?? false,
11
- error: state.follow.errors[userId] ?? null,
12
- });
13
-
14
- // Memoized selector for multiple users
15
- const createMultipleFollowSelector = (userIds: string[]) => (state: RootState) => {
16
- const followData: Record<string, { isFollowing: boolean; isLoading: boolean; error: string | null }> = {};
17
- const followState = state.follow;
18
-
19
- for (const userId of userIds) {
20
- followData[userId] = {
21
- isFollowing: followState.followingUsers[userId] ?? false,
22
- isLoading: followState.loadingUsers[userId] ?? false,
23
- error: followState.errors[userId] ?? null,
24
- };
25
- }
26
-
27
- return {
28
- followData,
29
- isAnyLoading: userIds.some(uid => followState.loadingUsers[uid]),
30
- hasAnyError: userIds.some(uid => followState.errors[uid]),
31
- allFollowing: userIds.every(uid => followState.followingUsers[uid]),
32
- allNotFollowing: userIds.every(uid => !followState.followingUsers[uid]),
33
- };
34
- };
35
-
36
- /**
37
- * Custom hook for managing follow/unfollow functionality
38
- * Optimized to prevent unnecessary re-renders
39
- * Can handle both single user and multiple users
40
- */
41
5
  export const useFollow = (userId?: string | string[]) => {
42
- const dispatch = useDispatch();
43
6
  const { oxyServices } = useOxy();
44
-
45
- // Memoize user IDs to prevent recreation on every render
46
- const userIds = useMemo(() => {
47
- return Array.isArray(userId) ? userId : userId ? [userId] : [];
48
- }, [userId]);
49
-
7
+ const userIds = useMemo(() => (Array.isArray(userId) ? userId : userId ? [userId] : []), [userId]);
50
8
  const isSingleUser = typeof userId === 'string';
51
-
52
- // Memoize selectors to prevent recreation
53
- const singleUserSelector = useMemo(() => {
54
- return isSingleUser && userId ? createFollowSelector(userId) : null;
55
- }, [isSingleUser, userId]);
56
-
57
- const multipleUserSelector = useMemo(() => {
58
- return !isSingleUser ? createMultipleFollowSelector(userIds) : null;
59
- }, [isSingleUser, userIds]);
60
-
61
- // Use appropriate selector based on mode
62
- const singleUserData = useSelector(singleUserSelector || (() => ({ isFollowing: false, isLoading: false, error: null })));
63
- const multipleUserData = useSelector(multipleUserSelector || (() => ({
64
- followData: {},
65
- isAnyLoading: false,
66
- hasAnyError: false,
67
- allFollowing: false,
68
- allNotFollowing: true
69
- })));
70
-
71
- // Memoized callbacks to prevent recreation on every render
9
+
10
+ // Zustand selectors
11
+ const followState = useFollowStore();
12
+
13
+ // Single user helpers
14
+ const isFollowing = isSingleUser && userId ? followState.followingUsers[userId] ?? false : false;
15
+ const isLoading = isSingleUser && userId ? followState.loadingUsers[userId] ?? false : false;
16
+ const error = isSingleUser && userId ? followState.errors[userId] ?? null : null;
17
+
72
18
  const toggleFollow = useCallback(async () => {
73
19
  if (!isSingleUser || !userId) throw new Error('toggleFollow is only available for single user mode');
74
-
75
- try {
76
- const result = await dispatch(toggleFollowUser({
77
- userId,
78
- oxyServices,
79
- isCurrentlyFollowing: singleUserData.isFollowing
80
- })).unwrap();
81
- return result;
82
- } catch (error) {
83
- throw error;
84
- }
85
- }, [dispatch, userId, oxyServices, singleUserData.isFollowing, isSingleUser]);
20
+ await followState.toggleFollowUser(userId, oxyServices, isFollowing);
21
+ }, [isSingleUser, userId, followState, oxyServices, isFollowing]);
86
22
 
87
23
  const setFollowStatus = useCallback((following: boolean) => {
88
24
  if (!isSingleUser || !userId) throw new Error('setFollowStatus is only available for single user mode');
89
- dispatch(setFollowingStatus({ userId, isFollowing: following }));
90
- }, [dispatch, userId, isSingleUser]);
25
+ followState.setFollowingStatus(userId, following);
26
+ }, [isSingleUser, userId, followState]);
91
27
 
92
28
  const fetchStatus = useCallback(async () => {
93
29
  if (!isSingleUser || !userId) throw new Error('fetchStatus is only available for single user mode');
94
-
95
- try {
96
- await dispatch(fetchFollowStatus({ userId, oxyServices })).unwrap();
97
- } catch (error) {
98
- console.warn(`Failed to fetch follow status for user ${userId}:`, error);
99
- }
100
- }, [dispatch, userId, oxyServices, isSingleUser]);
30
+ await followState.fetchFollowStatus(userId, oxyServices);
31
+ }, [isSingleUser, userId, followState, oxyServices]);
101
32
 
102
33
  const clearError = useCallback(() => {
103
34
  if (!isSingleUser || !userId) throw new Error('clearError is only available for single user mode');
104
- dispatch(clearFollowError(userId));
105
- }, [dispatch, userId, isSingleUser]);
35
+ followState.clearFollowError(userId);
36
+ }, [isSingleUser, userId, followState]);
37
+
38
+ // Multiple user helpers
39
+ const followData = useMemo(() => {
40
+ const data: Record<string, { isFollowing: boolean; isLoading: boolean; error: string | null }> = {};
41
+ userIds.forEach(uid => {
42
+ data[uid] = {
43
+ isFollowing: followState.followingUsers[uid] ?? false,
44
+ isLoading: followState.loadingUsers[uid] ?? false,
45
+ error: followState.errors[uid] ?? null,
46
+ };
47
+ });
48
+ return data;
49
+ }, [userIds, followState.followingUsers, followState.loadingUsers, followState.errors]);
106
50
 
107
- // Multiple user callbacks
108
51
  const toggleFollowForUser = useCallback(async (targetUserId: string) => {
109
- const currentState = multipleUserData.followData[targetUserId]?.isFollowing ?? false;
110
- try {
111
- const result = await dispatch(toggleFollowUser({
112
- userId: targetUserId,
113
- oxyServices,
114
- isCurrentlyFollowing: currentState
115
- })).unwrap();
116
- return result;
117
- } catch (error) {
118
- throw error;
119
- }
120
- }, [dispatch, oxyServices, multipleUserData.followData]);
52
+ const currentState = followState.followingUsers[targetUserId] ?? false;
53
+ await followState.toggleFollowUser(targetUserId, oxyServices, currentState);
54
+ }, [followState, oxyServices]);
121
55
 
122
56
  const setFollowStatusForUser = useCallback((targetUserId: string, following: boolean) => {
123
- dispatch(setFollowingStatus({ userId: targetUserId, isFollowing: following }));
124
- }, [dispatch]);
57
+ followState.setFollowingStatus(targetUserId, following);
58
+ }, [followState]);
125
59
 
126
60
  const fetchStatusForUser = useCallback(async (targetUserId: string) => {
127
- try {
128
- await dispatch(fetchFollowStatus({ userId: targetUserId, oxyServices })).unwrap();
129
- } catch (error) {
130
- console.warn(`Failed to fetch follow status for user ${targetUserId}:`, error);
131
- }
132
- }, [dispatch, oxyServices]);
61
+ await followState.fetchFollowStatus(targetUserId, oxyServices);
62
+ }, [followState, oxyServices]);
133
63
 
134
64
  const fetchAllStatuses = useCallback(async () => {
135
- const promises = userIds.map(uid =>
136
- dispatch(fetchFollowStatus({ userId: uid, oxyServices })).unwrap().catch((error: any) => {
137
- console.warn(`Failed to fetch follow status for user ${uid}:`, error);
138
- })
139
- );
140
- await Promise.all(promises);
141
- }, [dispatch, userIds, oxyServices]);
65
+ await Promise.all(userIds.map(uid => followState.fetchFollowStatus(uid, oxyServices)));
66
+ }, [userIds, followState, oxyServices]);
142
67
 
143
68
  const clearErrorForUser = useCallback((targetUserId: string) => {
144
- dispatch(clearFollowError(targetUserId));
145
- }, [dispatch]);
69
+ followState.clearFollowError(targetUserId);
70
+ }, [followState]);
71
+
72
+ // Aggregate helpers for multiple users
73
+ const isAnyLoading = userIds.some(uid => followState.loadingUsers[uid]);
74
+ const hasAnyError = userIds.some(uid => !!followState.errors[uid]);
75
+ const allFollowing = userIds.every(uid => followState.followingUsers[uid]);
76
+ const allNotFollowing = userIds.every(uid => !followState.followingUsers[uid]);
146
77
 
147
- // Return appropriate interface based on mode
148
78
  if (isSingleUser && userId) {
149
79
  return {
150
- isFollowing: singleUserData.isFollowing,
151
- isLoading: singleUserData.isLoading,
152
- error: singleUserData.error,
80
+ isFollowing,
81
+ isLoading,
82
+ error,
153
83
  toggleFollow,
154
84
  setFollowStatus,
155
85
  fetchStatus,
156
86
  clearError,
157
87
  };
158
88
  }
159
-
89
+
160
90
  return {
161
- followData: multipleUserData.followData,
91
+ followData,
162
92
  toggleFollowForUser,
163
93
  setFollowStatusForUser,
164
94
  fetchStatusForUser,
165
95
  fetchAllStatuses,
166
96
  clearErrorForUser,
167
- // Helper methods
168
- isAnyLoading: multipleUserData.isAnyLoading,
169
- hasAnyError: multipleUserData.hasAnyError,
170
- allFollowing: multipleUserData.allFollowing,
171
- allNotFollowing: multipleUserData.allNotFollowing,
97
+ isAnyLoading,
98
+ hasAnyError,
99
+ allFollowing,
100
+ allNotFollowing,
172
101
  };
173
102
  };
@@ -0,0 +1,50 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import io from 'socket.io-client';
3
+ import { toast } from '../../lib/sonner';
4
+
5
+ interface UseSessionSocketProps {
6
+ userId: string | null | undefined;
7
+ activeSessionId: string | null | undefined;
8
+ refreshSessions: () => Promise<void>;
9
+ logout: () => Promise<void>;
10
+ baseURL: string;
11
+ onRemoteSignOut?: () => void;
12
+ }
13
+
14
+ export function useSessionSocket({ userId, activeSessionId, refreshSessions, logout, baseURL, onRemoteSignOut }: UseSessionSocketProps) {
15
+ const socketRef = useRef<any>(null);
16
+
17
+ useEffect(() => {
18
+ if (!userId || !baseURL) return;
19
+
20
+ if (!socketRef.current) {
21
+ socketRef.current = io(baseURL, {
22
+ transports: ['websocket'],
23
+ });
24
+ }
25
+ const socket = socketRef.current;
26
+
27
+ socket.on('connect', () => {
28
+ console.log('Socket connected:', socket.id);
29
+ });
30
+
31
+ socket.emit('join', { userId: `user:${userId}` });
32
+ console.log('Emitting join for room:', `user:${userId}`);
33
+
34
+ socket.on('session_update', (data: { type: string; sessionId: string }) => {
35
+ console.log('Received session_update:', data);
36
+ if (data.sessionId === activeSessionId) {
37
+ if (onRemoteSignOut) onRemoteSignOut();
38
+ else toast.info('You have been signed out remotely.');
39
+ logout();
40
+ } else {
41
+ refreshSessions();
42
+ }
43
+ });
44
+
45
+ return () => {
46
+ socket.emit('leave', { userId: `user:${userId}` });
47
+ socket.off('session_update');
48
+ };
49
+ }, [userId, baseURL, activeSessionId, refreshSessions, logout, onRemoteSignOut]);
50
+ }
package/src/ui/index.ts CHANGED
@@ -8,6 +8,7 @@ export { default as OxySignInButton } from './components/OxySignInButton';
8
8
  export { default as OxyLogo } from './components/OxyLogo';
9
9
  export { default as Avatar } from './components/Avatar';
10
10
  export { default as FollowButton } from './components/FollowButton';
11
+ export { default as OxyPayButton } from './components/OxyPayButton';
11
12
  export { FontLoader, setupFonts } from './components/FontLoader';
12
13
 
13
14
  // Export icon components
@@ -21,41 +22,6 @@ export {
21
22
  OxyContextProviderProps
22
23
  } from './context/OxyContext';
23
24
 
24
- // Redux store exports - NEW ARCHITECTURE
25
- export {
26
- setupOxyStore,
27
- oxyReducers,
28
- // Individual slices
29
- authSlice,
30
- authActions,
31
- authSelectors,
32
- authReducer,
33
- followSlice,
34
- followActions,
35
- followSelectors,
36
- followThunks,
37
- followReducer,
38
- // Action creators
39
- loginStart,
40
- loginSuccess,
41
- loginFailure,
42
- logout,
43
- setFollowingStatus,
44
- clearFollowError,
45
- resetFollowState,
46
- fetchFollowStatus,
47
- toggleFollowUser,
48
- // Types
49
- AuthState,
50
- FollowState,
51
- initialAuthState,
52
- initialFollowState
53
- } from './store';
54
-
55
- // Legacy store exports (deprecated)
56
- export { store } from './store';
57
- export type { RootState, AppDispatch } from './store';
58
-
59
25
  // Export styles
60
26
  export { fontFamilies, fontStyles } from './styles/fonts';
61
27
 
@@ -63,8 +29,7 @@ export { fontFamilies, fontStyles } from './styles/fonts';
63
29
  export * from './navigation/types';
64
30
 
65
31
  // Hooks
66
- export { useOxyFollow, useFollow } from './hooks';
67
- export { default as useAuthFetch } from './hooks/useAuthFetch';
32
+ export { useFollow } from './hooks';
68
33
 
69
34
  // Screens
70
35
  export { default as ProfileScreen } from './screens/ProfileScreen';