react-native-stallion 1.1.2 → 2.0.0-alpha.2

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 (296) hide show
  1. package/android/src/main/java/com/stallion/Stallion.java +153 -9
  2. package/android/src/main/java/com/stallion/StallionModule.java +128 -167
  3. package/android/src/main/java/com/stallion/events/StallionEventConstants.java +22 -0
  4. package/android/src/main/java/com/stallion/events/StallionEventManager.java +160 -0
  5. package/android/src/main/java/com/stallion/networkmanager/StallionApiConstants.java +28 -0
  6. package/android/src/main/java/com/stallion/networkmanager/StallionApiManager.java +96 -0
  7. package/android/src/main/java/com/stallion/networkmanager/StallionDownloadCallback.java +7 -0
  8. package/android/src/main/java/com/stallion/networkmanager/StallionFileDownloader.java +224 -0
  9. package/android/src/main/java/com/stallion/networkmanager/StallionStageManager.java +77 -0
  10. package/android/src/main/java/com/stallion/networkmanager/StallionSyncHandler.java +183 -0
  11. package/android/src/main/java/com/stallion/storage/StallionConfig.java +120 -0
  12. package/android/src/main/java/com/stallion/storage/StallionConfigConstants.java +24 -0
  13. package/android/src/main/java/com/stallion/storage/StallionMeta.java +206 -0
  14. package/android/src/main/java/com/stallion/storage/StallionMetaConstants.java +30 -0
  15. package/android/src/main/java/com/stallion/storage/StallionStateManager.java +110 -0
  16. package/android/src/main/java/com/stallion/{StallionDefaultErrorActivity.java → utils/StallionErrorActivity.java} +11 -10
  17. package/android/src/main/java/com/stallion/utils/StallionExceptionHandler.java +102 -0
  18. package/android/src/main/java/com/stallion/utils/StallionFileManager.java +205 -0
  19. package/android/src/main/java/com/stallion/utils/StallionSlotManager.java +110 -0
  20. package/ios/main/Stallion-Bridging-Header.h +6 -1
  21. package/ios/main/Stallion.m +28 -9
  22. package/ios/main/Stallion.swift +132 -50
  23. package/ios/main/StallionConfig.h +24 -0
  24. package/ios/main/StallionConfig.m +62 -0
  25. package/ios/main/StallionConfigConstants.h +32 -0
  26. package/ios/main/StallionConfigConstants.m +32 -0
  27. package/ios/main/StallionConstants.swift +53 -10
  28. package/ios/main/StallionEventHandler.h +23 -0
  29. package/ios/main/StallionEventHandler.m +138 -0
  30. package/ios/main/StallionExceptionHandler.h +18 -0
  31. package/ios/main/StallionExceptionHandler.m +94 -0
  32. package/ios/main/StallionFileDownloader.swift +147 -0
  33. package/ios/main/StallionFileManager.h +20 -0
  34. package/ios/main/StallionFileManager.m +126 -0
  35. package/ios/main/StallionMeta.h +29 -0
  36. package/ios/main/StallionMeta.m +98 -0
  37. package/ios/main/StallionMetaConstants.h +28 -0
  38. package/ios/main/StallionMetaConstants.m +42 -0
  39. package/ios/main/StallionModule.m +137 -20
  40. package/ios/main/StallionObjConstants.h +47 -0
  41. package/ios/main/StallionObjConstants.m +128 -0
  42. package/ios/main/StallionSlotManager.h +21 -0
  43. package/ios/main/StallionSlotManager.m +114 -0
  44. package/ios/main/StallionStageManager.swift +84 -0
  45. package/ios/main/StallionStateManager.h +31 -0
  46. package/ios/main/StallionStateManager.m +87 -0
  47. package/ios/main/StallionSyncHandler.swift +212 -0
  48. package/package.json +6 -2
  49. package/src/index.js +5 -15
  50. package/src/index.js.map +1 -1
  51. package/src/main/components/common/ButtonFullWidth/styles.js +2 -2
  52. package/src/main/components/common/ButtonFullWidth/styles.js.map +1 -1
  53. package/src/main/components/common/Footer/index.js +24 -31
  54. package/src/main/components/common/Footer/index.js.map +1 -1
  55. package/src/main/components/common/Footer/styles.js +34 -33
  56. package/src/main/components/common/Footer/styles.js.map +1 -1
  57. package/src/main/components/common/Header/index.js +14 -17
  58. package/src/main/components/common/Header/index.js.map +1 -1
  59. package/src/main/components/common/Header/styles.js +10 -5
  60. package/src/main/components/common/Header/styles.js.map +1 -1
  61. package/src/main/components/common/Spinner/index.js +3 -1
  62. package/src/main/components/common/Spinner/index.js.map +1 -1
  63. package/src/main/components/modules/listing/components/BucketCard.js +3 -3
  64. package/src/main/components/modules/listing/components/BucketCard.js.map +1 -1
  65. package/src/main/components/modules/listing/components/BundleCard.js +9 -5
  66. package/src/main/components/modules/listing/components/BundleCard.js.map +1 -1
  67. package/src/main/components/modules/listing/components/BundleCardInfoSection.js +21 -12
  68. package/src/main/components/modules/listing/components/BundleCardInfoSection.js.map +1 -1
  69. package/src/main/components/modules/listing/components/CardDescriptionContent.js +3 -2
  70. package/src/main/components/modules/listing/components/CardDescriptionContent.js.map +1 -1
  71. package/src/main/components/modules/listing/components/ConfigView.js +19 -0
  72. package/src/main/components/modules/listing/components/ConfigView.js.map +1 -0
  73. package/src/main/components/modules/listing/components/MetaCard.js +38 -0
  74. package/src/main/components/modules/listing/components/MetaCard.js.map +1 -0
  75. package/src/main/components/modules/listing/components/SlotView.js +84 -0
  76. package/src/main/components/modules/listing/components/SlotView.js.map +1 -0
  77. package/src/main/components/modules/listing/components/styles/index.js +31 -10
  78. package/src/main/components/modules/listing/components/styles/index.js.map +1 -1
  79. package/src/main/components/modules/listing/hooks/useListing.js +5 -4
  80. package/src/main/components/modules/listing/hooks/useListing.js.map +1 -1
  81. package/src/main/components/modules/listing/index.js +12 -4
  82. package/src/main/components/modules/listing/index.js.map +1 -1
  83. package/src/main/components/modules/login/index.js +42 -38
  84. package/src/main/components/modules/login/index.js.map +1 -1
  85. package/src/main/components/modules/login/styles/index.js +21 -7
  86. package/src/main/components/modules/login/styles/index.js.map +1 -1
  87. package/src/main/components/modules/modal/StallionModal.js +28 -31
  88. package/src/main/components/modules/modal/StallionModal.js.map +1 -1
  89. package/src/main/components/modules/modal/hooks/useStallionModal.js +16 -52
  90. package/src/main/components/modules/modal/hooks/useStallionModal.js.map +1 -1
  91. package/src/main/components/modules/prod/index.js +3 -0
  92. package/src/main/components/modules/prod/index.js.map +1 -0
  93. package/src/main/components/modules/prod/prod.js +35 -0
  94. package/src/main/components/modules/prod/prod.js.map +1 -0
  95. package/src/main/components/modules/prod/styles/index.js +23 -0
  96. package/src/main/components/modules/prod/styles/index.js.map +1 -0
  97. package/src/main/constants/apiConstants.js +4 -2
  98. package/src/main/constants/apiConstants.js.map +1 -1
  99. package/src/main/constants/appConstants.js +43 -7
  100. package/src/main/constants/appConstants.js.map +1 -1
  101. package/src/main/constants/colors.js +8 -6
  102. package/src/main/constants/colors.js.map +1 -1
  103. package/src/main/state/actionCreators/useBucketActions.js +10 -13
  104. package/src/main/state/actionCreators/useBucketActions.js.map +1 -1
  105. package/src/main/state/actionCreators/useBundleActions.js +14 -17
  106. package/src/main/state/actionCreators/useBundleActions.js.map +1 -1
  107. package/src/main/state/actionCreators/useConfigActions.js +20 -0
  108. package/src/main/state/actionCreators/useConfigActions.js.map +1 -0
  109. package/src/main/state/actionCreators/useDownloadActions.js +20 -42
  110. package/src/main/state/actionCreators/useDownloadActions.js.map +1 -1
  111. package/src/main/state/actionCreators/useMetaActions.js +6 -5
  112. package/src/main/state/actionCreators/useMetaActions.js.map +1 -1
  113. package/src/main/state/actionCreators/useUpdateMetaActions.js +77 -0
  114. package/src/main/state/actionCreators/useUpdateMetaActions.js.map +1 -0
  115. package/src/main/state/actionCreators/useUserActions.js +25 -85
  116. package/src/main/state/actionCreators/useUserActions.js.map +1 -1
  117. package/src/main/state/actions/configActions.js +8 -0
  118. package/src/main/state/actions/configActions.js.map +1 -0
  119. package/src/main/state/actions/userActions.js +3 -15
  120. package/src/main/state/actions/userActions.js.map +1 -1
  121. package/src/main/state/index.js +30 -13
  122. package/src/main/state/index.js.map +1 -1
  123. package/src/main/state/reducers/configReducer.js +19 -0
  124. package/src/main/state/reducers/configReducer.js.map +1 -0
  125. package/src/main/state/reducers/updateMetaReducer.js +36 -0
  126. package/src/main/state/reducers/updateMetaReducer.js.map +1 -0
  127. package/src/main/state/reducers/userReducer.js +3 -37
  128. package/src/main/state/reducers/userReducer.js.map +1 -1
  129. package/src/main/state/useStallionEvents.js +102 -0
  130. package/src/main/state/useStallionEvents.js.map +1 -0
  131. package/src/main/utils/ErrorBoundary.js +19 -16
  132. package/src/main/utils/ErrorBoundary.js.map +1 -1
  133. package/src/main/utils/StallionEventEmitter.js +20 -0
  134. package/src/main/utils/StallionEventEmitter.js.map +1 -0
  135. package/src/main/utils/StallionNativeUtils.js +35 -0
  136. package/src/main/utils/StallionNativeUtils.js.map +1 -0
  137. package/src/main/utils/debounce.js +16 -0
  138. package/src/main/utils/debounce.js.map +1 -0
  139. package/src/main/utils/useApiClient.js +28 -0
  140. package/src/main/utils/useApiClient.js.map +1 -0
  141. package/src/main/utils/useStallionModal.js +4 -3
  142. package/src/main/utils/useStallionModal.js.map +1 -1
  143. package/src/main/utils/useStallionUpdate.js +14 -0
  144. package/src/main/utils/useStallionUpdate.js.map +1 -0
  145. package/src/main/utils/withStallion.js +1 -4
  146. package/src/main/utils/withStallion.js.map +1 -1
  147. package/src/types/config.types.js +5 -0
  148. package/src/types/config.types.js.map +1 -0
  149. package/src/types/meta.types.js +11 -0
  150. package/src/types/meta.types.js.map +1 -1
  151. package/src/types/updateMeta.types.js +7 -0
  152. package/src/types/updateMeta.types.js.map +1 -0
  153. package/src/types/user.types.js +1 -2
  154. package/src/types/user.types.js.map +1 -1
  155. package/types/index.d.ts +3 -0
  156. package/types/index.d.ts.map +1 -1
  157. package/types/main/components/common/Footer/index.d.ts +1 -4
  158. package/types/main/components/common/Footer/index.d.ts.map +1 -1
  159. package/types/main/components/common/Footer/styles.d.ts +30 -29
  160. package/types/main/components/common/Footer/styles.d.ts.map +1 -1
  161. package/types/main/components/common/Header/index.d.ts +0 -2
  162. package/types/main/components/common/Header/index.d.ts.map +1 -1
  163. package/types/main/components/common/Header/styles.d.ts +6 -1
  164. package/types/main/components/common/Header/styles.d.ts.map +1 -1
  165. package/types/main/components/common/Spinner/index.d.ts.map +1 -1
  166. package/types/main/components/modules/listing/components/BucketCard.d.ts.map +1 -1
  167. package/types/main/components/modules/listing/components/BundleCard.d.ts.map +1 -1
  168. package/types/main/components/modules/listing/components/BundleCardInfoSection.d.ts +2 -0
  169. package/types/main/components/modules/listing/components/BundleCardInfoSection.d.ts.map +1 -1
  170. package/types/main/components/modules/listing/components/CardDescriptionContent.d.ts.map +1 -1
  171. package/types/main/components/modules/listing/components/ConfigView.d.ts +8 -0
  172. package/types/main/components/modules/listing/components/ConfigView.d.ts.map +1 -0
  173. package/types/main/components/modules/listing/components/MetaCard.d.ts +8 -0
  174. package/types/main/components/modules/listing/components/MetaCard.d.ts.map +1 -0
  175. package/types/main/components/modules/listing/components/SlotView.d.ts +5 -0
  176. package/types/main/components/modules/listing/components/SlotView.d.ts.map +1 -0
  177. package/types/main/components/modules/listing/components/styles/index.d.ts +26 -5
  178. package/types/main/components/modules/listing/components/styles/index.d.ts.map +1 -1
  179. package/types/main/components/modules/listing/hooks/useListing.d.ts +2 -0
  180. package/types/main/components/modules/listing/hooks/useListing.d.ts.map +1 -1
  181. package/types/main/components/modules/listing/index.d.ts.map +1 -1
  182. package/types/main/components/modules/login/index.d.ts.map +1 -1
  183. package/types/main/components/modules/login/styles/index.d.ts +17 -3
  184. package/types/main/components/modules/login/styles/index.d.ts.map +1 -1
  185. package/types/main/components/modules/modal/StallionModal.d.ts.map +1 -1
  186. package/types/main/components/modules/modal/hooks/useStallionModal.d.ts +2 -11
  187. package/types/main/components/modules/modal/hooks/useStallionModal.d.ts.map +1 -1
  188. package/types/main/components/modules/prod/index.d.ts +3 -0
  189. package/types/main/components/modules/prod/index.d.ts.map +1 -0
  190. package/types/main/components/modules/prod/prod.d.ts +4 -0
  191. package/types/main/components/modules/prod/prod.d.ts.map +1 -0
  192. package/types/main/components/modules/prod/styles/index.d.ts +19 -0
  193. package/types/main/components/modules/prod/styles/index.d.ts.map +1 -0
  194. package/types/main/constants/apiConstants.d.ts +5 -3
  195. package/types/main/constants/apiConstants.d.ts.map +1 -1
  196. package/types/main/constants/appConstants.d.ts +40 -7
  197. package/types/main/constants/appConstants.d.ts.map +1 -1
  198. package/types/main/constants/colors.d.ts +2 -0
  199. package/types/main/constants/colors.d.ts.map +1 -1
  200. package/types/main/index.d.ts +1 -1
  201. package/types/main/state/actionCreators/useBucketActions.d.ts +2 -1
  202. package/types/main/state/actionCreators/useBucketActions.d.ts.map +1 -1
  203. package/types/main/state/actionCreators/useBundleActions.d.ts +2 -1
  204. package/types/main/state/actionCreators/useBundleActions.d.ts.map +1 -1
  205. package/types/main/state/actionCreators/useConfigActions.d.ts +7 -0
  206. package/types/main/state/actionCreators/useConfigActions.d.ts.map +1 -0
  207. package/types/main/state/actionCreators/useDownloadActions.d.ts +5 -2
  208. package/types/main/state/actionCreators/useDownloadActions.d.ts.map +1 -1
  209. package/types/main/state/actionCreators/useMetaActions.d.ts +1 -1
  210. package/types/main/state/actionCreators/useMetaActions.d.ts.map +1 -1
  211. package/types/main/state/actionCreators/useUpdateMetaActions.d.ts +8 -0
  212. package/types/main/state/actionCreators/useUpdateMetaActions.d.ts.map +1 -0
  213. package/types/main/state/actionCreators/useUserActions.d.ts +5 -7
  214. package/types/main/state/actionCreators/useUserActions.d.ts.map +1 -1
  215. package/types/main/state/actions/configActions.d.ts +3 -0
  216. package/types/main/state/actions/configActions.d.ts.map +1 -0
  217. package/types/main/state/actions/userActions.d.ts +2 -4
  218. package/types/main/state/actions/userActions.d.ts.map +1 -1
  219. package/types/main/state/index.d.ts.map +1 -1
  220. package/types/main/state/reducers/configReducer.d.ts +4 -0
  221. package/types/main/state/reducers/configReducer.d.ts.map +1 -0
  222. package/types/main/state/reducers/updateMetaReducer.d.ts +10 -0
  223. package/types/main/state/reducers/updateMetaReducer.d.ts.map +1 -0
  224. package/types/main/state/reducers/userReducer.d.ts.map +1 -1
  225. package/types/main/state/useStallionEvents.d.ts +12 -0
  226. package/types/main/state/useStallionEvents.d.ts.map +1 -0
  227. package/types/main/utils/ErrorBoundary.d.ts +1 -1
  228. package/types/main/utils/ErrorBoundary.d.ts.map +1 -1
  229. package/types/main/utils/StallionEventEmitter.d.ts +11 -0
  230. package/types/main/utils/StallionEventEmitter.d.ts.map +1 -0
  231. package/types/main/utils/StallionNativeUtils.d.ts +11 -0
  232. package/types/main/utils/StallionNativeUtils.d.ts.map +1 -0
  233. package/types/main/utils/debounce.d.ts +3 -0
  234. package/types/main/utils/debounce.d.ts.map +1 -0
  235. package/types/main/utils/useApiClient.d.ts +8 -0
  236. package/types/main/utils/useApiClient.d.ts.map +1 -0
  237. package/types/main/utils/useStallionUpdate.d.ts +3 -0
  238. package/types/main/utils/useStallionUpdate.d.ts.map +1 -0
  239. package/types/main/utils/withStallion.d.ts +1 -2
  240. package/types/main/utils/withStallion.d.ts.map +1 -1
  241. package/types/types/config.types.d.ts +16 -0
  242. package/types/types/config.types.d.ts.map +1 -0
  243. package/types/types/globalProvider.types.d.ts +10 -10
  244. package/types/types/globalProvider.types.d.ts.map +1 -1
  245. package/types/types/meta.types.d.ts +18 -3
  246. package/types/types/meta.types.d.ts.map +1 -1
  247. package/types/types/updateMeta.types.d.ts +37 -0
  248. package/types/types/updateMeta.types.d.ts.map +1 -0
  249. package/types/types/user.types.d.ts +5 -20
  250. package/types/types/user.types.d.ts.map +1 -1
  251. package/types/types/utils.types.d.ts +15 -11
  252. package/types/types/utils.types.d.ts.map +1 -1
  253. package/android/src/main/java/com/stallion/StallionConstants.java +0 -37
  254. package/android/src/main/java/com/stallion/StallionErrorBoundary.java +0 -49
  255. package/android/src/main/java/com/stallion/StallionStorage.java +0 -54
  256. package/android/src/main/java/com/stallion/StallionZip.java +0 -127
  257. package/ios/main/StallionDownloader.swift +0 -124
  258. package/ios/main/StallionErrorBoundary.h +0 -17
  259. package/ios/main/StallionErrorBoundary.m +0 -62
  260. package/ios/main/StallionUtil.swift +0 -29
  261. package/src/main/components/common/ProfileOverlay/index.js +0 -39
  262. package/src/main/components/common/ProfileOverlay/index.js.map +0 -1
  263. package/src/main/components/common/ProfileOverlay/styles.js +0 -39
  264. package/src/main/components/common/ProfileOverlay/styles.js.map +0 -1
  265. package/src/main/components/modules/login/components/Email.js +0 -41
  266. package/src/main/components/modules/login/components/Email.js.map +0 -1
  267. package/src/main/components/modules/login/components/Otp.js +0 -45
  268. package/src/main/components/modules/login/components/Otp.js.map +0 -1
  269. package/src/main/components/modules/login/components/styles/index.js +0 -28
  270. package/src/main/components/modules/login/components/styles/index.js.map +0 -1
  271. package/src/main/components/modules/login/hooks/useLoginFlow.js +0 -60
  272. package/src/main/components/modules/login/hooks/useLoginFlow.js.map +0 -1
  273. package/src/main/utils/SharedDataManager.js +0 -34
  274. package/src/main/utils/SharedDataManager.js.map +0 -1
  275. package/src/main/utils/StallionNaitveUtils.js +0 -7
  276. package/src/main/utils/StallionNaitveUtils.js.map +0 -1
  277. package/src/main/utils/apiUtils.js +0 -16
  278. package/src/main/utils/apiUtils.js.map +0 -1
  279. package/types/main/components/common/ProfileOverlay/index.d.ts +0 -10
  280. package/types/main/components/common/ProfileOverlay/index.d.ts.map +0 -1
  281. package/types/main/components/common/ProfileOverlay/styles.d.ts +0 -36
  282. package/types/main/components/common/ProfileOverlay/styles.d.ts.map +0 -1
  283. package/types/main/components/modules/login/components/Email.d.ts +0 -13
  284. package/types/main/components/modules/login/components/Email.d.ts.map +0 -1
  285. package/types/main/components/modules/login/components/Otp.d.ts +0 -12
  286. package/types/main/components/modules/login/components/Otp.d.ts.map +0 -1
  287. package/types/main/components/modules/login/components/styles/index.d.ts +0 -25
  288. package/types/main/components/modules/login/components/styles/index.d.ts.map +0 -1
  289. package/types/main/components/modules/login/hooks/useLoginFlow.d.ts +0 -18
  290. package/types/main/components/modules/login/hooks/useLoginFlow.d.ts.map +0 -1
  291. package/types/main/utils/SharedDataManager.d.ts +0 -18
  292. package/types/main/utils/SharedDataManager.d.ts.map +0 -1
  293. package/types/main/utils/StallionNaitveUtils.d.ts +0 -7
  294. package/types/main/utils/StallionNaitveUtils.d.ts.map +0 -1
  295. package/types/main/utils/apiUtils.d.ts +0 -7
  296. package/types/main/utils/apiUtils.d.ts.map +0 -1
@@ -0,0 +1,160 @@
1
+ package com.stallion.events;
2
+
3
+ import com.facebook.react.modules.core.DeviceEventManagerModule;
4
+ import com.stallion.storage.StallionConfig;
5
+ import com.stallion.storage.StallionConfigConstants;
6
+ import com.stallion.storage.StallionStateManager;
7
+
8
+ import org.json.JSONArray;
9
+ import org.json.JSONException;
10
+ import org.json.JSONObject;
11
+
12
+ import java.util.Iterator;
13
+ import java.util.List;
14
+ import java.util.UUID;
15
+
16
+ public class StallionEventManager {
17
+ public static final String STALLION_NATIVE_EVENT_NAME = "STALLION_NATIVE_EVENT";
18
+ private static final String EVENTS_KEY = "stored_events";
19
+ private static final int MAX_BATCH_COUNT_SIZE = 9;
20
+
21
+ private static StallionEventManager instance;
22
+ private final StallionStateManager stallionStateManager;
23
+ private DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter;
24
+
25
+ // Private constructor for Singleton
26
+ private StallionEventManager(StallionStateManager stateManager) {
27
+ this.stallionStateManager = stateManager;
28
+ }
29
+
30
+ // Singleton initialization method
31
+ public static synchronized void init(StallionStateManager stateManager) {
32
+ if (instance == null) {
33
+ instance = new StallionEventManager(stateManager);
34
+ }
35
+ }
36
+
37
+ public void setEmitter(DeviceEventManagerModule.RCTDeviceEventEmitter deviceEmitter) {
38
+ eventEmitter = deviceEmitter;
39
+ }
40
+
41
+ // Get instance method
42
+ public static synchronized StallionEventManager getInstance() {
43
+ if (instance == null) {
44
+ throw new IllegalStateException("StallionEventManager is not initialized. Call init() first.");
45
+ }
46
+ return instance;
47
+ }
48
+
49
+ public void sendEventWithoutCaching(String eventName, JSONObject eventPayload) {
50
+ try {
51
+ eventPayload.put("type", eventName);
52
+
53
+ // Emit the event to React Native
54
+ if (eventEmitter != null) {
55
+ eventEmitter.emit(STALLION_NATIVE_EVENT_NAME, eventPayload.toString());
56
+ }
57
+
58
+ } catch (JSONException e) {
59
+ e.printStackTrace();
60
+ }
61
+ }
62
+
63
+ // Method to send an event
64
+ public void sendEvent(String eventName, JSONObject eventPayload) {
65
+ try {
66
+ StallionConfig stallionConfig = this.stallionStateManager.getStallionConfig();
67
+ // Generate a unique ID for the event
68
+ String uniqueId = UUID.randomUUID().toString();
69
+
70
+ eventPayload.put("type", eventName);
71
+
72
+ // Emit the event to React Native
73
+ if (eventEmitter != null) {
74
+ eventEmitter.emit(STALLION_NATIVE_EVENT_NAME, eventPayload.toString());
75
+ }
76
+
77
+ // change type for sending to server
78
+ eventPayload.remove("type");
79
+ eventPayload.put("eventType", eventName);
80
+
81
+ // Add unique ID and timestamp to the event payload
82
+ eventPayload.put("eventId", uniqueId);
83
+ eventPayload.put("eventTimestamp", System.currentTimeMillis());
84
+ eventPayload.put("projectId", stallionConfig.getProjectId());
85
+ eventPayload.put("platform", StallionConfigConstants.PLATFORM);
86
+ eventPayload.put("appVersion", stallionConfig.getAppVersion());
87
+ eventPayload.put("uid", stallionConfig.getUid());
88
+
89
+ // Store the event locally
90
+ storeEventLocally(uniqueId, eventPayload);
91
+
92
+ } catch (JSONException e) {
93
+ e.printStackTrace();
94
+ }
95
+ }
96
+
97
+ // Store the event locally in SharedPreferences
98
+ private void storeEventLocally(String uniqueId, JSONObject eventPayload) {
99
+ try {
100
+ String eventsString = stallionStateManager.getString(EVENTS_KEY, "{}");
101
+ JSONObject eventsObject = new JSONObject(eventsString);
102
+ eventsObject.put(uniqueId, eventPayload.toString());
103
+ stallionStateManager.setString(EVENTS_KEY, eventsObject.toString());
104
+ } catch (JSONException e) {
105
+ cleanupEventStorage();
106
+ e.printStackTrace();
107
+ }
108
+ }
109
+
110
+ private void cleanupEventStorage() {
111
+ stallionStateManager.setString(EVENTS_KEY, "{}");
112
+ }
113
+
114
+ // Method to pop events as a batch
115
+ public String popEvents() {
116
+ try {
117
+ String eventsString = stallionStateManager.getString(EVENTS_KEY, "{}");
118
+ JSONObject eventsObject = new JSONObject(eventsString);
119
+
120
+ JSONArray batch = new JSONArray();
121
+ Iterator<String> keys = eventsObject.keys();
122
+
123
+ int count = 0;
124
+ while (keys.hasNext() && count < MAX_BATCH_COUNT_SIZE) {
125
+ String key = keys.next();
126
+ batch.put(new JSONObject(eventsObject.getString(key)));
127
+ count++;
128
+ }
129
+
130
+ return batch.toString();
131
+
132
+ } catch (JSONException e) {
133
+ cleanupEventStorage();
134
+ e.printStackTrace();
135
+ }
136
+
137
+ return "[]"; // Return an empty array if there are no events
138
+ }
139
+
140
+ // Acknowledge events by deleting them from local storage
141
+ public void acknowledgeEvents(List<String> eventIds) {
142
+ try {
143
+ String eventsString = stallionStateManager.getString(EVENTS_KEY, "{}");
144
+ JSONObject eventsObject = new JSONObject(eventsString);
145
+
146
+ // Remove each event by its unique ID
147
+ for (String eventId : eventIds) {
148
+ if (eventsObject.has(eventId)) {
149
+ eventsObject.remove(eventId);
150
+ }
151
+ }
152
+
153
+ // Update the SharedPreferences with the modified events
154
+ stallionStateManager.setString(EVENTS_KEY, eventsObject.toString());
155
+
156
+ } catch (JSONException e) {
157
+ e.printStackTrace();
158
+ }
159
+ }
160
+ }
@@ -0,0 +1,28 @@
1
+ package com.stallion.networkmanager;
2
+
3
+ public class StallionApiConstants {
4
+ // Buffer Size
5
+ public static final int DOWNLOAD_BUFFER_SIZE = 1024 * 256;
6
+
7
+ // File and Folder Names
8
+ public static final String ZIP_FILE_NAME = "build.zip";
9
+ public static final String UNZIP_FOLDER_NAME = "/build";
10
+ public static final String ANDROID_BUNDLE_FILE_NAME = "/index.android.bundle";
11
+
12
+ // Error Messages
13
+ public static final String DOWNLOAD_ERROR_PREFIX = "Stallion download error: ";
14
+ public static final String DOWNLOAD_FILESYSTEM_ERROR_MESSAGE = "Filesystem error in download";
15
+ public static final String CORRUPTED_FILE_ERROR = "Corrupted file";
16
+
17
+ // Success Messages
18
+ public static final String DOWNLOAD_SUCCESS_MESSAGE = "Success";
19
+
20
+ // API Tokens
21
+ public static final String STALLION_APP_TOKEN_KEY = "x-app-token";
22
+ public static final String STALLION_SDK_TOKEN_KEY = "x-sdk-pin-access-token";
23
+ public static final String STALLION_DEVICE_ID_KEY = "uid";
24
+
25
+
26
+ public static final String STALLION_API_BASE = "https://api.stalliontech.io";
27
+ public static final String STALLION_INFO_API_PATH = "/api/v1/promoted/get-update-meta";
28
+ }
@@ -0,0 +1,96 @@
1
+ package com.stallion.networkmanager;
2
+
3
+ import org.json.JSONException;
4
+ import org.json.JSONObject;
5
+
6
+ import java.io.BufferedReader;
7
+ import java.io.IOException;
8
+ import java.io.InputStream;
9
+ import java.io.InputStreamReader;
10
+ import java.io.OutputStream;
11
+ import java.io.OutputStreamWriter;
12
+ import java.net.HttpURLConnection;
13
+ import java.net.URL;
14
+ import java.nio.charset.StandardCharsets;
15
+
16
+ import com.stallion.storage.StallionConfig;
17
+ import com.stallion.storage.StallionStateManager;
18
+
19
+ public class StallionApiManager {
20
+
21
+ public static JSONObject post(String urlString, String requestBodyString) {
22
+ HttpURLConnection urlConnection = null;
23
+ try {
24
+ StallionStateManager stallionStateManager = StallionStateManager.getInstance();
25
+ StallionConfig stallionConfig = stallionStateManager.getStallionConfig();
26
+
27
+ // Set up the connection
28
+ URL url = new URL(urlString);
29
+ urlConnection = (HttpURLConnection) url.openConnection();
30
+ urlConnection.setRequestMethod("POST");
31
+ urlConnection.setRequestProperty("Content-Type", "application/json");
32
+
33
+ String appToken = stallionConfig.getAppToken();
34
+ String sdkToken = stallionConfig.getSdkToken();
35
+ String uid = stallionConfig.getUid();
36
+
37
+ if(appToken != null && !appToken.isEmpty()) {
38
+ urlConnection.setRequestProperty(StallionApiConstants.STALLION_APP_TOKEN_KEY, appToken);
39
+ }
40
+
41
+ if (sdkToken != null && !sdkToken.isEmpty()) {
42
+ urlConnection.setRequestProperty(StallionApiConstants.STALLION_SDK_TOKEN_KEY, sdkToken);
43
+ }
44
+
45
+ if (uid != null && !uid.isEmpty()) {
46
+ urlConnection.setRequestProperty(StallionApiConstants.STALLION_DEVICE_ID_KEY, uid);
47
+ }
48
+
49
+ urlConnection.setDoOutput(true);
50
+
51
+ // Write the request body
52
+ try (OutputStream os = urlConnection.getOutputStream();
53
+ OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
54
+ osw.write(requestBodyString);
55
+ osw.flush();
56
+ }
57
+
58
+ // Connect and check response code
59
+ int responseCode = urlConnection.getResponseCode();
60
+ if (responseCode != HttpURLConnection.HTTP_OK) {
61
+ throw new IOException("HTTP error code: " + responseCode);
62
+ }
63
+
64
+ // Read the response
65
+ StringBuilder result = new StringBuilder();
66
+ try (InputStream in = urlConnection.getInputStream();
67
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
68
+ String line;
69
+ while ((line = reader.readLine()) != null) {
70
+ result.append(line);
71
+ }
72
+ }
73
+
74
+ // Parse and return JSON
75
+ return new JSONObject(result.toString());
76
+
77
+ } catch (Exception e) {
78
+ e.printStackTrace();
79
+
80
+ // Return an error JSON object
81
+ JSONObject error = new JSONObject();
82
+ try {
83
+ error.put("error", e.getMessage());
84
+ } catch (JSONException jsonException) {
85
+ jsonException.printStackTrace();
86
+ }
87
+ return error;
88
+
89
+ } finally {
90
+ if (urlConnection != null) {
91
+ urlConnection.disconnect();
92
+ }
93
+ }
94
+ }
95
+ }
96
+
@@ -0,0 +1,7 @@
1
+ package com.stallion.networkmanager;
2
+
3
+ public interface StallionDownloadCallback {
4
+ void onReject(String prefix, String error);
5
+ void onSuccess(String successPayload);
6
+ void onProgress(double downloadFraction);
7
+ }
@@ -0,0 +1,224 @@
1
+ package com.stallion.networkmanager;
2
+
3
+ import android.os.StatFs;
4
+
5
+ import java.io.BufferedInputStream;
6
+ import java.io.BufferedOutputStream;
7
+ import java.io.File;
8
+ import java.io.FileInputStream;
9
+ import java.io.FileOutputStream;
10
+ import java.io.IOException;
11
+ import java.net.HttpURLConnection;
12
+ import java.net.URL;
13
+ import java.nio.ByteBuffer;
14
+ import java.util.concurrent.ExecutorService;
15
+ import java.util.concurrent.Executors;
16
+
17
+ import android.util.Log;
18
+
19
+ import com.stallion.storage.StallionConfig;
20
+ import com.stallion.storage.StallionStateManager;
21
+ import com.stallion.utils.StallionFileManager;
22
+
23
+ public class StallionFileDownloader {
24
+
25
+ private static final String TAG = "StallionFileDownloader";
26
+ private static final ExecutorService executor = Executors.newSingleThreadExecutor();
27
+
28
+ public static void downloadBundle(
29
+ String downloadUrl,
30
+ String downloadDirectory,
31
+ StallionDownloadCallback stallionDownloadCallback
32
+ ) {
33
+ executor.execute(() -> {
34
+ try {
35
+ // Prepare for download
36
+ File downloadedZip = prepareForDownload(downloadDirectory);
37
+
38
+ // Fetch appToken and apiKey
39
+ StallionStateManager stateManager = StallionStateManager.getInstance();
40
+ StallionConfig config = stateManager.getStallionConfig();
41
+ String appToken = config.getAppToken();
42
+ String sdkToken = config.getSdkToken();
43
+
44
+ // Get file size
45
+ long fileSize = getFileSize(downloadUrl, appToken, sdkToken);
46
+ if (fileSize <= 0) {
47
+ stallionDownloadCallback.onReject(
48
+ StallionApiConstants.DOWNLOAD_ERROR_PREFIX,
49
+ "File size is zero or unknown"
50
+ );
51
+ return;
52
+ }
53
+
54
+ // Check available storage
55
+ if (!isEnoughSpaceAvailable(downloadDirectory, fileSize)) {
56
+ stallionDownloadCallback.onReject(
57
+ StallionApiConstants.DOWNLOAD_ERROR_PREFIX,
58
+ "Not enough space to download the file"
59
+ );
60
+ return;
61
+ }
62
+
63
+ // Download file
64
+ downloadFile(downloadUrl, downloadedZip, appToken, sdkToken, stallionDownloadCallback);
65
+
66
+ // Validate and unzip the downloaded file
67
+ validateAndUnzip(downloadedZip, downloadDirectory, stallionDownloadCallback);
68
+
69
+ } catch (Exception e) {
70
+ Log.e(TAG, "Error in downloadBundle: " + e.getMessage(), e);
71
+ }
72
+ });
73
+ }
74
+
75
+ private static long getFileSize(String downloadUrl, String appToken, String apiKey) throws IOException {
76
+ HttpURLConnection connection = null;
77
+ try {
78
+ connection = setupConnection(downloadUrl, appToken, apiKey);
79
+ return connection.getContentLength();
80
+ } finally {
81
+ if (connection != null) {
82
+ connection.disconnect();
83
+ }
84
+ }
85
+ }
86
+
87
+ private static boolean isEnoughSpaceAvailable(String directoryPath, long fileSize) {
88
+ File directory = new File(directoryPath);
89
+ if (!directory.exists()) {
90
+ directory.mkdirs();
91
+ }
92
+ StatFs statFs = new StatFs(directory.getPath());
93
+ long availableBytes = (long) statFs.getAvailableBlocksLong() * statFs.getBlockSizeLong();
94
+ return availableBytes >= fileSize;
95
+ }
96
+
97
+ private static File prepareForDownload(String downloadDirectory) throws IOException {
98
+ File downloadFolder = new File(downloadDirectory);
99
+ if (downloadFolder.exists()) {
100
+ StallionFileManager.deleteFileOrFolderSilently(downloadFolder);
101
+ }
102
+ if (!downloadFolder.mkdirs()) {
103
+ throw new IOException("Failed to create download directory: " + downloadDirectory);
104
+ }
105
+ return new File(downloadFolder, StallionApiConstants.ZIP_FILE_NAME);
106
+ }
107
+
108
+ private static void downloadFile(
109
+ String downloadUrl,
110
+ File destinationFile,
111
+ String appToken,
112
+ String sdkToken,
113
+ StallionDownloadCallback callback
114
+ ) throws IOException {
115
+ HttpURLConnection connection = null;
116
+ try (
117
+ BufferedInputStream inputStream = new BufferedInputStream(setupConnection(downloadUrl, appToken, sdkToken).getInputStream());
118
+ FileOutputStream fout = new FileOutputStream(destinationFile);
119
+ BufferedOutputStream bout = new BufferedOutputStream(fout, StallionApiConstants.DOWNLOAD_BUFFER_SIZE)
120
+ ) {
121
+ connection = setupConnection(downloadUrl, appToken, sdkToken);
122
+
123
+ byte[] buffer = new byte[StallionApiConstants.DOWNLOAD_BUFFER_SIZE];
124
+ long totalBytes = connection.getContentLength();
125
+ long receivedBytes = 0;
126
+ int bytesRead;
127
+ double lastProgress = 0;
128
+
129
+ // Ensure totalBytes is valid
130
+ if (totalBytes <= 0) {
131
+ callback.onReject(StallionApiConstants.DOWNLOAD_ERROR_PREFIX, "Invalid content length: " + totalBytes);
132
+ return;
133
+ }
134
+
135
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
136
+ bout.write(buffer, 0, bytesRead);
137
+ receivedBytes += bytesRead;
138
+
139
+ double progress = (double) receivedBytes / totalBytes;
140
+ if (Double.isNaN(progress) || Double.isInfinite(progress)) {
141
+ callback.onReject(StallionApiConstants.DOWNLOAD_ERROR_PREFIX, "Invalid progress calculation");
142
+ return;
143
+ }
144
+
145
+ if (progress - lastProgress >= 0.1) {
146
+ lastProgress = progress;
147
+ callback.onProgress(progress);
148
+ }
149
+ }
150
+
151
+ bout.close();
152
+ fout.close();
153
+ inputStream.close();
154
+
155
+ // Check for incomplete download
156
+ if (receivedBytes < totalBytes) {
157
+ callback.onReject(StallionApiConstants.DOWNLOAD_ERROR_PREFIX, "Incomplete file download");
158
+ return;
159
+ }
160
+ } catch (IOException e) {
161
+ callback.onReject(StallionApiConstants.DOWNLOAD_ERROR_PREFIX, "IOException occurred: " + e.getMessage());
162
+ throw e;
163
+ } finally {
164
+ if (connection != null) {
165
+ connection.disconnect();
166
+ }
167
+ }
168
+ }
169
+
170
+
171
+ private static HttpURLConnection setupConnection(String downloadUrl, String appToken, String sdkToken) throws IOException {
172
+ URL url = new URL(downloadUrl);
173
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
174
+ connection.setRequestMethod("GET");
175
+
176
+ if(!appToken.isEmpty()) {
177
+ connection.setRequestProperty(StallionApiConstants.STALLION_APP_TOKEN_KEY, appToken);
178
+ }
179
+ if(!sdkToken.isEmpty()) {
180
+ connection.setRequestProperty(StallionApiConstants.STALLION_SDK_TOKEN_KEY, sdkToken);
181
+ }
182
+
183
+ connection.setDoInput(true);
184
+ connection.connect();
185
+ return connection;
186
+ }
187
+
188
+ private static void validateAndUnzip(
189
+ File downloadedZip,
190
+ String destDirectory,
191
+ StallionDownloadCallback callback
192
+ ) {
193
+ try {
194
+ if (!isValidZip(downloadedZip)) {
195
+ callback.onReject(StallionApiConstants.DOWNLOAD_ERROR_PREFIX, "Invalid ZIP file");
196
+ return;
197
+ }
198
+
199
+ StallionFileManager.unzipFile(downloadedZip.getAbsolutePath(), destDirectory);
200
+
201
+ File otaBundle = new File(destDirectory + StallionApiConstants.UNZIP_FOLDER_NAME + StallionApiConstants.ANDROID_BUNDLE_FILE_NAME);
202
+ if (otaBundle.exists()) {
203
+ callback.onSuccess(StallionApiConstants.DOWNLOAD_SUCCESS_MESSAGE);
204
+ } else {
205
+ callback.onReject(StallionApiConstants.DOWNLOAD_ERROR_PREFIX, StallionApiConstants.CORRUPTED_FILE_ERROR);
206
+ }
207
+ } catch (Exception e) {
208
+ String filesystemError = e.getMessage();
209
+ callback.onReject(StallionApiConstants.DOWNLOAD_ERROR_PREFIX, StallionApiConstants.DOWNLOAD_FILESYSTEM_ERROR_MESSAGE + filesystemError);
210
+ } finally {
211
+ StallionFileManager.deleteFileOrFolderSilently(downloadedZip);
212
+ }
213
+ }
214
+
215
+ private static boolean isValidZip(File file) throws IOException {
216
+ try (FileInputStream fis = new FileInputStream(file)) {
217
+ byte[] header = new byte[4];
218
+ if (fis.read(header) != 4) {
219
+ return false;
220
+ }
221
+ return ByteBuffer.wrap(header).getInt() == 0x504b0304;
222
+ }
223
+ }
224
+ }
@@ -0,0 +1,77 @@
1
+ package com.stallion.networkmanager;
2
+
3
+ import com.facebook.react.bridge.Promise;
4
+ import com.facebook.react.bridge.ReadableMap;
5
+ import com.stallion.events.StallionEventConstants;
6
+ import com.stallion.events.StallionEventManager;
7
+ import com.stallion.storage.StallionConfigConstants;
8
+ import com.stallion.storage.StallionMetaConstants;
9
+ import com.stallion.storage.StallionStateManager;
10
+
11
+ import org.json.JSONObject;
12
+
13
+ public class StallionStageManager {
14
+ public static void downloadStageBundle(ReadableMap bundleInfo, Promise promise) {
15
+ StallionStateManager stallionStateManager = StallionStateManager.getInstance();
16
+ String receivedDownloadUrl = bundleInfo.getString("url");
17
+ String receivedHash = bundleInfo.getString("hash");
18
+ if(
19
+ receivedDownloadUrl != null
20
+ && !receivedDownloadUrl.isEmpty()
21
+ && receivedHash != null
22
+ && !receivedHash.isEmpty()
23
+ ) {
24
+ String downloadPath = stallionStateManager.getStallionConfig().getFilesDirectory()
25
+ + StallionConfigConstants.STAGE_DIRECTORY
26
+ + StallionConfigConstants.TEMP_FOLDER_SLOT;
27
+
28
+ StallionFileDownloader.downloadBundle(
29
+ receivedDownloadUrl,
30
+ downloadPath,
31
+ new StallionDownloadCallback() {
32
+ @Override
33
+ public void onReject(String prefix, String error) {
34
+ promise.reject(prefix, error);
35
+ }
36
+
37
+ @Override
38
+ public void onSuccess(String successPayload) {
39
+ stallionStateManager.stallionMeta.setCurrentStageSlot(StallionMetaConstants.SlotStates.NEW_SLOT);
40
+ stallionStateManager.stallionMeta.setStageTempHash(receivedHash);
41
+ stallionStateManager.syncStallionMeta();
42
+ emitDownloadSuccessStage(receivedHash);
43
+ promise.resolve(successPayload);
44
+ }
45
+
46
+ @Override
47
+ public void onProgress(double downloadFraction) {
48
+ emitDownloadProgressStage(receivedHash, downloadFraction);
49
+ }
50
+ }
51
+ );
52
+ }
53
+ }
54
+
55
+ private static void emitDownloadSuccessStage(String releaseHash) {
56
+ JSONObject successPayload = new JSONObject();
57
+ try {
58
+ successPayload.put("releaseHash", releaseHash);
59
+ } catch (Exception ignored) { }
60
+ StallionEventManager.getInstance().sendEventWithoutCaching(
61
+ StallionEventConstants.NativeStageEventTypes.DOWNLOAD_COMPLETE_STAGE.toString(),
62
+ successPayload
63
+ );
64
+ }
65
+
66
+ private static void emitDownloadProgressStage(String releaseHash, double newProgress) {
67
+ JSONObject successPayload = new JSONObject();
68
+ try {
69
+ successPayload.put("releaseHash", releaseHash);
70
+ successPayload.put("progress", String.valueOf(newProgress));
71
+ } catch (Exception ignored) { }
72
+ StallionEventManager.getInstance().sendEventWithoutCaching(
73
+ StallionEventConstants.NativeStageEventTypes.DOWNLOAD_PROGRESS_STAGE.toString(),
74
+ successPayload
75
+ );
76
+ }
77
+ }