react-native-stallion 1.1.2 → 2.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/stallion/Stallion.java +94 -10
- package/android/src/main/java/com/stallion/StallionApiUtil.java +58 -0
- package/android/src/main/java/com/stallion/StallionCommonUtil.java +25 -0
- package/android/src/main/java/com/stallion/StallionConstants.java +51 -15
- package/android/src/main/java/com/stallion/StallionDownloadCallback.java +7 -0
- package/android/src/main/java/com/stallion/StallionDownloadManager.java +121 -0
- package/android/src/main/java/com/stallion/StallionErrorBoundary.java +28 -4
- package/android/src/main/java/com/stallion/StallionEventEmitter.java +144 -0
- package/android/src/main/java/com/stallion/StallionFileUtil.java +129 -0
- package/android/src/main/java/com/stallion/StallionModule.java +100 -154
- package/android/src/main/java/com/stallion/StallionRollbackManager.java +82 -0
- package/android/src/main/java/com/stallion/StallionStorage.java +16 -6
- package/android/src/main/java/com/stallion/StallionSynManager.java +142 -0
- package/ios/main/Stallion-Bridging-Header.h +4 -0
- package/ios/main/Stallion.m +7 -5
- package/ios/main/Stallion.swift +80 -39
- package/ios/main/StallionConstants.swift +52 -10
- package/ios/main/StallionDownloader.swift +39 -52
- package/ios/main/StallionErrorBoundary.h +1 -1
- package/ios/main/StallionErrorBoundary.m +45 -28
- package/ios/main/StallionEventEmitter.swift +20 -0
- package/ios/main/StallionEventManager.h +21 -0
- package/ios/main/StallionEventManager.m +57 -0
- package/ios/main/StallionModule.m +107 -23
- package/ios/main/StallionObjConstants.h +46 -0
- package/ios/main/StallionObjConstants.m +124 -0
- package/ios/main/StallionObjUtil.h +14 -0
- package/ios/main/StallionObjUtil.m +22 -0
- package/ios/main/StallionRollbackHandler.h +22 -0
- package/ios/main/StallionRollbackHandler.m +128 -0
- package/ios/main/StallionSyncManager.swift +149 -0
- package/ios/main/StallionUtil.swift +2 -12
- package/package.json +6 -2
- package/src/index.js +5 -15
- package/src/index.js.map +1 -1
- package/src/main/components/common/ButtonFullWidth/styles.js +2 -2
- package/src/main/components/common/ButtonFullWidth/styles.js.map +1 -1
- package/src/main/components/common/Footer/index.js +24 -31
- package/src/main/components/common/Footer/index.js.map +1 -1
- package/src/main/components/common/Footer/styles.js +34 -33
- package/src/main/components/common/Footer/styles.js.map +1 -1
- package/src/main/components/common/Header/index.js +12 -8
- package/src/main/components/common/Header/index.js.map +1 -1
- package/src/main/components/common/Header/styles.js +10 -5
- package/src/main/components/common/Header/styles.js.map +1 -1
- package/src/main/components/common/ProfileOverlay/index.js +18 -7
- package/src/main/components/common/ProfileOverlay/index.js.map +1 -1
- package/src/main/components/common/ProfileOverlay/styles.js +41 -8
- package/src/main/components/common/ProfileOverlay/styles.js.map +1 -1
- package/src/main/components/common/Spinner/index.js +3 -1
- package/src/main/components/common/Spinner/index.js.map +1 -1
- package/src/main/components/modules/listing/components/BucketCard.js +3 -3
- package/src/main/components/modules/listing/components/BucketCard.js.map +1 -1
- package/src/main/components/modules/listing/components/BundleCard.js +9 -5
- package/src/main/components/modules/listing/components/BundleCard.js.map +1 -1
- package/src/main/components/modules/listing/components/BundleCardInfoSection.js +20 -12
- package/src/main/components/modules/listing/components/BundleCardInfoSection.js.map +1 -1
- package/src/main/components/modules/listing/components/CardDescriptionContent.js +3 -2
- package/src/main/components/modules/listing/components/CardDescriptionContent.js.map +1 -1
- package/src/main/components/modules/listing/components/MetaCard.js +38 -0
- package/src/main/components/modules/listing/components/MetaCard.js.map +1 -0
- package/src/main/components/modules/listing/components/SlotView.js +82 -0
- package/src/main/components/modules/listing/components/SlotView.js.map +1 -0
- package/src/main/components/modules/listing/components/styles/index.js +28 -9
- package/src/main/components/modules/listing/components/styles/index.js.map +1 -1
- package/src/main/components/modules/listing/hooks/useListing.js +9 -2
- package/src/main/components/modules/listing/hooks/useListing.js.map +1 -1
- package/src/main/components/modules/listing/index.js +12 -4
- package/src/main/components/modules/listing/index.js.map +1 -1
- package/src/main/components/modules/login/components/styles/index.js +4 -4
- package/src/main/components/modules/login/components/styles/index.js.map +1 -1
- package/src/main/components/modules/login/index.js +1 -1
- package/src/main/components/modules/login/index.js.map +1 -1
- package/src/main/components/modules/login/styles/index.js +7 -6
- package/src/main/components/modules/login/styles/index.js.map +1 -1
- package/src/main/components/modules/modal/StallionModal.js +13 -11
- package/src/main/components/modules/modal/StallionModal.js.map +1 -1
- package/src/main/components/modules/modal/hooks/useStallionModal.js +87 -24
- package/src/main/components/modules/modal/hooks/useStallionModal.js.map +1 -1
- package/src/main/components/modules/prod/index.js +3 -0
- package/src/main/components/modules/prod/index.js.map +1 -0
- package/src/main/components/modules/prod/prod.js +35 -0
- package/src/main/components/modules/prod/prod.js.map +1 -0
- package/src/main/components/modules/prod/styles/index.js +20 -0
- package/src/main/components/modules/prod/styles/index.js.map +1 -0
- package/src/main/constants/apiConstants.js +3 -1
- package/src/main/constants/apiConstants.js.map +1 -1
- package/src/main/constants/appConstants.js +40 -4
- package/src/main/constants/appConstants.js.map +1 -1
- package/src/main/constants/colors.js +8 -6
- package/src/main/constants/colors.js.map +1 -1
- package/src/main/state/actionCreators/useDownloadActions.js +17 -37
- package/src/main/state/actionCreators/useDownloadActions.js.map +1 -1
- package/src/main/state/actionCreators/useMetaActions.js +4 -5
- package/src/main/state/actionCreators/useMetaActions.js.map +1 -1
- package/src/main/state/actionCreators/useUpdateMetaActions.js +100 -0
- package/src/main/state/actionCreators/useUpdateMetaActions.js.map +1 -0
- package/src/main/state/actionCreators/useUserActions.js +4 -4
- package/src/main/state/actionCreators/useUserActions.js.map +1 -1
- package/src/main/state/index.js +15 -2
- package/src/main/state/index.js.map +1 -1
- package/src/main/state/reducers/updateMetaReducer.js +36 -0
- package/src/main/state/reducers/updateMetaReducer.js.map +1 -0
- package/src/main/utils/ErrorBoundary.js +15 -14
- package/src/main/utils/ErrorBoundary.js.map +1 -1
- package/src/main/utils/EventUtil.js +28 -0
- package/src/main/utils/EventUtil.js.map +1 -0
- package/src/main/utils/SharedDataManager.js +15 -12
- package/src/main/utils/SharedDataManager.js.map +1 -1
- package/src/main/utils/StallionEventEmitter.js +20 -0
- package/src/main/utils/StallionEventEmitter.js.map +1 -0
- package/src/main/utils/StallionNativeUtils.js +60 -0
- package/src/main/utils/StallionNativeUtils.js.map +1 -0
- package/src/main/utils/apiUtils.js +8 -0
- package/src/main/utils/apiUtils.js.map +1 -1
- package/src/main/utils/useStallionModal.js +4 -3
- package/src/main/utils/useStallionModal.js.map +1 -1
- package/src/main/utils/useStallionUpdate.js +13 -0
- package/src/main/utils/useStallionUpdate.js.map +1 -0
- package/src/main/utils/withStallion.js +1 -4
- package/src/main/utils/withStallion.js.map +1 -1
- package/src/types/meta.types.js +13 -0
- package/src/types/meta.types.js.map +1 -1
- package/src/types/updateMeta.types.js +7 -0
- package/src/types/updateMeta.types.js.map +1 -0
- package/types/index.d.ts +3 -0
- package/types/index.d.ts.map +1 -1
- package/types/main/components/common/Footer/index.d.ts +1 -4
- package/types/main/components/common/Footer/index.d.ts.map +1 -1
- package/types/main/components/common/Footer/styles.d.ts +30 -29
- package/types/main/components/common/Footer/styles.d.ts.map +1 -1
- package/types/main/components/common/Header/index.d.ts.map +1 -1
- package/types/main/components/common/Header/styles.d.ts +6 -1
- package/types/main/components/common/Header/styles.d.ts.map +1 -1
- package/types/main/components/common/ProfileOverlay/index.d.ts.map +1 -1
- package/types/main/components/common/ProfileOverlay/styles.d.ts +38 -5
- package/types/main/components/common/ProfileOverlay/styles.d.ts.map +1 -1
- package/types/main/components/common/Spinner/index.d.ts.map +1 -1
- package/types/main/components/modules/listing/components/BucketCard.d.ts.map +1 -1
- package/types/main/components/modules/listing/components/BundleCard.d.ts.map +1 -1
- package/types/main/components/modules/listing/components/BundleCardInfoSection.d.ts +2 -0
- package/types/main/components/modules/listing/components/BundleCardInfoSection.d.ts.map +1 -1
- package/types/main/components/modules/listing/components/CardDescriptionContent.d.ts.map +1 -1
- package/types/main/components/modules/listing/components/MetaCard.d.ts +8 -0
- package/types/main/components/modules/listing/components/MetaCard.d.ts.map +1 -0
- package/types/main/components/modules/listing/components/SlotView.d.ts +5 -0
- package/types/main/components/modules/listing/components/SlotView.d.ts.map +1 -0
- package/types/main/components/modules/listing/components/styles/index.d.ts +24 -5
- package/types/main/components/modules/listing/components/styles/index.d.ts.map +1 -1
- package/types/main/components/modules/listing/hooks/useListing.d.ts +2 -0
- package/types/main/components/modules/listing/hooks/useListing.d.ts.map +1 -1
- package/types/main/components/modules/listing/index.d.ts.map +1 -1
- package/types/main/components/modules/login/components/styles/index.d.ts +1 -1
- package/types/main/components/modules/login/styles/index.d.ts +4 -3
- package/types/main/components/modules/login/styles/index.d.ts.map +1 -1
- package/types/main/components/modules/modal/StallionModal.d.ts.map +1 -1
- package/types/main/components/modules/modal/hooks/useStallionModal.d.ts +2 -5
- package/types/main/components/modules/modal/hooks/useStallionModal.d.ts.map +1 -1
- package/types/main/components/modules/prod/index.d.ts +3 -0
- package/types/main/components/modules/prod/index.d.ts.map +1 -0
- package/types/main/components/modules/prod/prod.d.ts +4 -0
- package/types/main/components/modules/prod/prod.d.ts.map +1 -0
- package/types/main/components/modules/prod/styles/index.d.ts +16 -0
- package/types/main/components/modules/prod/styles/index.d.ts.map +1 -0
- package/types/main/constants/apiConstants.d.ts +4 -2
- package/types/main/constants/apiConstants.d.ts.map +1 -1
- package/types/main/constants/appConstants.d.ts +37 -4
- package/types/main/constants/appConstants.d.ts.map +1 -1
- package/types/main/constants/colors.d.ts +2 -0
- package/types/main/constants/colors.d.ts.map +1 -1
- package/types/main/index.d.ts +1 -1
- package/types/main/state/actionCreators/useDownloadActions.d.ts +3 -1
- package/types/main/state/actionCreators/useDownloadActions.d.ts.map +1 -1
- package/types/main/state/actionCreators/useMetaActions.d.ts +1 -1
- package/types/main/state/actionCreators/useMetaActions.d.ts.map +1 -1
- package/types/main/state/actionCreators/useUpdateMetaActions.d.ts +7 -0
- package/types/main/state/actionCreators/useUpdateMetaActions.d.ts.map +1 -0
- package/types/main/state/index.d.ts.map +1 -1
- package/types/main/state/reducers/updateMetaReducer.d.ts +9 -0
- package/types/main/state/reducers/updateMetaReducer.d.ts.map +1 -0
- package/types/main/utils/ErrorBoundary.d.ts +1 -1
- package/types/main/utils/ErrorBoundary.d.ts.map +1 -1
- package/types/main/utils/EventUtil.d.ts +9 -0
- package/types/main/utils/EventUtil.d.ts.map +1 -0
- package/types/main/utils/SharedDataManager.d.ts +8 -6
- package/types/main/utils/SharedDataManager.d.ts.map +1 -1
- package/types/main/utils/StallionEventEmitter.d.ts +14 -0
- package/types/main/utils/StallionEventEmitter.d.ts.map +1 -0
- package/types/main/utils/StallionNativeUtils.d.ts +15 -0
- package/types/main/utils/StallionNativeUtils.d.ts.map +1 -0
- package/types/main/utils/apiUtils.d.ts +5 -0
- package/types/main/utils/apiUtils.d.ts.map +1 -1
- package/types/main/utils/useStallionUpdate.d.ts +3 -0
- package/types/main/utils/useStallionUpdate.d.ts.map +1 -0
- package/types/main/utils/withStallion.d.ts +1 -2
- package/types/main/utils/withStallion.d.ts.map +1 -1
- package/types/types/globalProvider.types.d.ts +5 -1
- package/types/types/globalProvider.types.d.ts.map +1 -1
- package/types/types/meta.types.d.ts +19 -3
- package/types/types/meta.types.d.ts.map +1 -1
- package/types/types/updateMeta.types.d.ts +35 -0
- package/types/types/updateMeta.types.d.ts.map +1 -0
- package/types/types/utils.types.d.ts +9 -7
- package/types/types/utils.types.d.ts.map +1 -1
- package/android/src/main/java/com/stallion/StallionZip.java +0 -127
- package/src/main/utils/StallionNaitveUtils.js +0 -7
- package/src/main/utils/StallionNaitveUtils.js.map +0 -1
- package/types/main/utils/StallionNaitveUtils.d.ts +0 -7
- package/types/main/utils/StallionNaitveUtils.d.ts.map +0 -1
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
package com.stallion;
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
|
+
import android.content.pm.PackageInfo;
|
|
5
|
+
import android.content.pm.PackageManager;
|
|
6
|
+
|
|
7
|
+
import com.facebook.react.bridge.Arguments;
|
|
8
|
+
import com.facebook.react.bridge.WritableMap;
|
|
9
|
+
|
|
10
|
+
import java.io.File;
|
|
4
11
|
|
|
5
12
|
public class Stallion {
|
|
6
13
|
|
|
@@ -8,19 +15,96 @@ public class Stallion {
|
|
|
8
15
|
return getJSBundleFile(applicationContext, null);
|
|
9
16
|
}
|
|
10
17
|
|
|
18
|
+
private static String getDefaultBundle(String defaultBundlePath) {
|
|
19
|
+
if(defaultBundlePath != null && !defaultBundlePath.isEmpty()) {
|
|
20
|
+
return defaultBundlePath;
|
|
21
|
+
} else {
|
|
22
|
+
return StallionConstants.DEFAULT_JS_BUNDLE_LOCATION_BASE + StallionConstants.ANDROID_BUNDLE_FILE_NAME;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private static String getAppVersion() throws PackageManager.NameNotFoundException {
|
|
27
|
+
Context appContext = StallionStorage.getInstance().mContext;
|
|
28
|
+
String parentPackageName= appContext.getPackageName();
|
|
29
|
+
PackageInfo pInfo = appContext.getPackageManager().getPackageInfo(parentPackageName, 0);
|
|
30
|
+
return pInfo.versionName;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private static void sendInstallEvent(String installedReleaseHash) {
|
|
34
|
+
WritableMap successEventPayload = Arguments.createMap();
|
|
35
|
+
successEventPayload.putString("releaseHash", installedReleaseHash);
|
|
36
|
+
StallionEventEmitter.sendEvent(
|
|
37
|
+
StallionEventEmitter.getEventPayload(
|
|
38
|
+
StallionConstants.NativeEventTypesProd.INSTALLED_PROD.toString(),
|
|
39
|
+
successEventPayload
|
|
40
|
+
)
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
11
44
|
public static String getJSBundleFile(Context applicationContext, String defaultBundlePath) {
|
|
12
45
|
StallionStorage.getInstance().Initialize(applicationContext);
|
|
13
46
|
StallionStorage stallionStorageInstance = StallionStorage.getInstance();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
47
|
+
String baseFolderPath = applicationContext.getFilesDir().getAbsolutePath();
|
|
48
|
+
String switchState = stallionStorageInstance.get(StallionConstants.STALLION_SWITCH_STATE_IDENTIFIER);
|
|
49
|
+
String currentAppVersion = "";
|
|
50
|
+
try {
|
|
51
|
+
String stallionAppVersionCache = stallionStorageInstance.get(StallionConstants.STALLION_APP_VERSION_IDENTIFIER);
|
|
52
|
+
currentAppVersion = getAppVersion();
|
|
53
|
+
if(!stallionAppVersionCache.equals(currentAppVersion)) {
|
|
54
|
+
stallionStorageInstance.set(StallionConstants.STALLION_APP_VERSION_IDENTIFIER, currentAppVersion);
|
|
55
|
+
StallionRollbackManager.fallbackProd();
|
|
56
|
+
}
|
|
57
|
+
} catch (PackageManager.NameNotFoundException e) {}
|
|
58
|
+
|
|
59
|
+
if(switchState.isEmpty()) {
|
|
60
|
+
stallionStorageInstance.set(StallionConstants.STALLION_SWITCH_STATE_IDENTIFIER, StallionConstants.SwitchState.PROD.toString());
|
|
61
|
+
switchState = StallionConstants.SwitchState.PROD.toString();
|
|
62
|
+
}
|
|
63
|
+
if(switchState.equals(StallionConstants.SwitchState.PROD.toString())) {
|
|
64
|
+
String currentProdSlot = stallionStorageInstance.get(StallionConstants.CURRENT_PROD_SLOT_KEY);
|
|
65
|
+
switch (currentProdSlot) {
|
|
66
|
+
case StallionConstants.TEMP_FOLDER_SLOT:
|
|
67
|
+
String newReleaseHash = stallionStorageInstance.get(StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT);
|
|
68
|
+
if(!newReleaseHash.isEmpty()) {
|
|
69
|
+
StallionRollbackManager.stabilizeRelease();
|
|
70
|
+
}
|
|
71
|
+
StallionFileUtil.moveFile(
|
|
72
|
+
new File(baseFolderPath, StallionConstants.PROD_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT),
|
|
73
|
+
new File(baseFolderPath, StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT)
|
|
74
|
+
);
|
|
75
|
+
String tempReleaseHash = stallionStorageInstance.get(StallionConstants.PROD_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT);
|
|
76
|
+
stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT, tempReleaseHash);
|
|
77
|
+
stallionStorageInstance.set(StallionConstants.CURRENT_PROD_SLOT_KEY, StallionConstants.NEW_FOLDER_SLOT);
|
|
78
|
+
stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT, "");
|
|
79
|
+
sendInstallEvent(tempReleaseHash);
|
|
80
|
+
return baseFolderPath + StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT + StallionConstants.UNZIP_FOLDER_NAME + StallionConstants.ANDROID_BUNDLE_FILE_NAME;
|
|
81
|
+
case StallionConstants.NEW_FOLDER_SLOT:
|
|
82
|
+
return baseFolderPath + StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT + StallionConstants.UNZIP_FOLDER_NAME + StallionConstants.ANDROID_BUNDLE_FILE_NAME;
|
|
83
|
+
case StallionConstants.STABLE_FOLDER_SLOT:
|
|
84
|
+
return baseFolderPath + StallionConstants.PROD_DIRECTORY + StallionConstants.STABLE_FOLDER_SLOT + StallionConstants.UNZIP_FOLDER_NAME + StallionConstants.ANDROID_BUNDLE_FILE_NAME;
|
|
85
|
+
default:
|
|
86
|
+
return getDefaultBundle(defaultBundlePath);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if(switchState.equals(StallionConstants.SwitchState.STAGE.toString())) {
|
|
90
|
+
String currentStageSlot = stallionStorageInstance.get(StallionConstants.CURRENT_STAGE_SLOT_KEY);
|
|
91
|
+
switch (currentStageSlot) {
|
|
92
|
+
case StallionConstants.TEMP_FOLDER_SLOT:
|
|
93
|
+
StallionFileUtil.moveFile(
|
|
94
|
+
new File(baseFolderPath, StallionConstants.STAGE_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT),
|
|
95
|
+
new File(baseFolderPath, StallionConstants.STAGE_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT)
|
|
96
|
+
);
|
|
97
|
+
String tempReleaseHash = stallionStorageInstance.get(StallionConstants.STAGE_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT);
|
|
98
|
+
stallionStorageInstance.set(StallionConstants.STAGE_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT, tempReleaseHash);
|
|
99
|
+
stallionStorageInstance.set(StallionConstants.STAGE_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT, "");
|
|
100
|
+
stallionStorageInstance.set(StallionConstants.CURRENT_STAGE_SLOT_KEY, StallionConstants.NEW_FOLDER_SLOT);
|
|
101
|
+
return baseFolderPath + StallionConstants.STAGE_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT + StallionConstants.UNZIP_FOLDER_NAME + StallionConstants.ANDROID_BUNDLE_FILE_NAME;
|
|
102
|
+
case StallionConstants.NEW_FOLDER_SLOT:
|
|
103
|
+
return baseFolderPath + StallionConstants.STAGE_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT + StallionConstants.UNZIP_FOLDER_NAME + StallionConstants.ANDROID_BUNDLE_FILE_NAME;
|
|
104
|
+
default:
|
|
105
|
+
return getDefaultBundle(defaultBundlePath);
|
|
106
|
+
}
|
|
24
107
|
}
|
|
108
|
+
return getDefaultBundle(defaultBundlePath);
|
|
25
109
|
}
|
|
26
110
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
package com.stallion;
|
|
2
|
+
|
|
3
|
+
import org.json.JSONObject;
|
|
4
|
+
import java.io.BufferedInputStream;
|
|
5
|
+
import java.io.BufferedReader;
|
|
6
|
+
import java.io.InputStream;
|
|
7
|
+
import java.io.InputStreamReader;
|
|
8
|
+
import java.io.OutputStream;
|
|
9
|
+
import java.io.OutputStreamWriter;
|
|
10
|
+
import java.net.HttpURLConnection;
|
|
11
|
+
import java.net.URL;
|
|
12
|
+
|
|
13
|
+
public class StallionApiUtil {
|
|
14
|
+
public static JSONObject post(String urlString, String requestBodyString, String token, String sdkToken) {
|
|
15
|
+
StringBuilder result = new StringBuilder();
|
|
16
|
+
HttpURLConnection urlConnection = null;
|
|
17
|
+
try {
|
|
18
|
+
URL url = new URL(urlString);
|
|
19
|
+
urlConnection = (HttpURLConnection) url.openConnection();
|
|
20
|
+
urlConnection.setRequestMethod("POST");
|
|
21
|
+
urlConnection.setRequestProperty("Content-Type", "application/json");
|
|
22
|
+
urlConnection.setRequestProperty(StallionConstants.STALLION_APP_TOKEN_KEY, token);
|
|
23
|
+
if(!sdkToken.isEmpty()) {
|
|
24
|
+
urlConnection.setRequestProperty(StallionConstants.STALLION_SDK_TOKEN_KEY, sdkToken);
|
|
25
|
+
}
|
|
26
|
+
urlConnection.setRequestProperty(StallionConstants.STALLION_DEVICE_ID_KEY, StallionCommonUtil.getUniqueId());
|
|
27
|
+
|
|
28
|
+
urlConnection.setDoOutput(true);
|
|
29
|
+
|
|
30
|
+
OutputStream os = urlConnection.getOutputStream();
|
|
31
|
+
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
|
|
32
|
+
osw.write(requestBodyString);
|
|
33
|
+
osw.flush();
|
|
34
|
+
osw.close();
|
|
35
|
+
os.close();
|
|
36
|
+
|
|
37
|
+
urlConnection.connect();
|
|
38
|
+
|
|
39
|
+
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
|
|
40
|
+
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
|
41
|
+
String line;
|
|
42
|
+
while ((line = reader.readLine()) != null) {
|
|
43
|
+
result.append(line);
|
|
44
|
+
}
|
|
45
|
+
} catch (Exception e) {
|
|
46
|
+
e.printStackTrace();
|
|
47
|
+
} finally {
|
|
48
|
+
if (urlConnection != null) {
|
|
49
|
+
urlConnection.disconnect();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
return new JSONObject(result.toString());
|
|
54
|
+
} catch (Exception e) {
|
|
55
|
+
return new JSONObject();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package com.stallion;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.provider.Settings;
|
|
5
|
+
|
|
6
|
+
import java.util.UUID;
|
|
7
|
+
|
|
8
|
+
public class StallionCommonUtil {
|
|
9
|
+
public static String getUniqueId() {
|
|
10
|
+
StallionStorage stallionStorage = StallionStorage.getInstance();
|
|
11
|
+
String cachedUniqueId = stallionStorage.get(StallionConstants.UNIQUE_ID_IDENTIFIER);
|
|
12
|
+
if(!cachedUniqueId.isEmpty()) {
|
|
13
|
+
return cachedUniqueId;
|
|
14
|
+
}
|
|
15
|
+
String uniqueId;
|
|
16
|
+
try {
|
|
17
|
+
Context currContext = StallionStorage.getInstance().mContext;
|
|
18
|
+
uniqueId = Settings.Secure.getString(currContext.getContentResolver(), Settings.Secure.ANDROID_ID);
|
|
19
|
+
} catch (Exception e) {
|
|
20
|
+
uniqueId = UUID.randomUUID().toString();
|
|
21
|
+
}
|
|
22
|
+
stallionStorage.set(StallionConstants.UNIQUE_ID_IDENTIFIER, uniqueId);
|
|
23
|
+
return uniqueId;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -2,26 +2,17 @@ package com.stallion;
|
|
|
2
2
|
|
|
3
3
|
public class StallionConstants {
|
|
4
4
|
public static final String MODULE_NAME = "Stallion";
|
|
5
|
-
public static final String STALLION_PACKAGE_PATH = "/StallionPackage";
|
|
6
5
|
public static final int DOWNLOAD_BUFFER_SIZE = 1024 * 256;
|
|
7
6
|
|
|
8
7
|
public static final String DOWNLOAD_ERROR_PREFIX = "Stallion download error: ";
|
|
9
|
-
|
|
10
|
-
public static final String BUNDLE_DEST_FOLDER_DIR = "/stallion-build";
|
|
11
|
-
public static final String SLOT_FOLDER_DIR = "/slots/";
|
|
8
|
+
|
|
12
9
|
public static final String ZIP_FILE_NAME = "build.zip";
|
|
13
|
-
public static final String UNZIP_FOLDER_NAME = "build";
|
|
14
|
-
public static final String ANDROID_BUNDLE_FILE_NAME = "index.android.bundle";
|
|
15
|
-
public static final String DEFAULT_JS_BUNDLE_LOCATION_BASE = "assets
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
public static final String ACTIVE_BUCKET_IDENTIFIER = "activeBucket";
|
|
19
|
-
public static final String ACTIVE_VERSION_IDENTIFIER = "activeVersion";
|
|
20
|
-
public static final String ACTIVE_SLOT_IDENTIFIER = "activeSlot";
|
|
10
|
+
public static final String UNZIP_FOLDER_NAME = "/build";
|
|
11
|
+
public static final String ANDROID_BUNDLE_FILE_NAME = "/index.android.bundle";
|
|
12
|
+
public static final String DEFAULT_JS_BUNDLE_LOCATION_BASE = "assets:/";
|
|
13
|
+
|
|
21
14
|
public static final String STALLION_SWITCH_STATE_IDENTIFIER = "switchState";
|
|
22
|
-
public static final String
|
|
23
|
-
public static final String STALLION_SWITCH_ON = "STALLION_ON";
|
|
24
|
-
public static final String STALLION_SWITCH_OFF = "DEFAULT";
|
|
15
|
+
public static final String STALLION_APP_VERSION_IDENTIFIER = "stallionAppVersion";
|
|
25
16
|
|
|
26
17
|
public static final String DOWNLOAD_SUCCESS_MESSAGE = "Success";
|
|
27
18
|
|
|
@@ -33,5 +24,50 @@ public class StallionConstants {
|
|
|
33
24
|
|
|
34
25
|
public static final String DOWNLOAD_DELETE_ERROR = "Download operation cleanup error";
|
|
35
26
|
|
|
27
|
+
|
|
28
|
+
public static final String PROD_DIRECTORY = "/StallionProd";
|
|
29
|
+
public static final String STAGE_DIRECTORY = "/StallionStage";
|
|
30
|
+
public static final String TEMP_FOLDER_SLOT = "/temp";
|
|
31
|
+
public static final String NEW_FOLDER_SLOT = "/StallionNew";
|
|
32
|
+
public static final String STABLE_FOLDER_SLOT = "/StallionStable";
|
|
33
|
+
public static final String DEFAULT_FOLDER_SLOT = "/Default";
|
|
34
|
+
|
|
35
|
+
public static final String CURRENT_PROD_SLOT_KEY = "stallionProdCurrentSlot";
|
|
36
|
+
public static final String CURRENT_STAGE_SLOT_KEY = "stallionStageCurrentSlot";
|
|
37
|
+
public static final String STALLION_API_BASE = "https://api.stalliontech.io";
|
|
38
|
+
public static final String STALLION_INFO_API_PATH = "/api/v1/promoted/get-update-meta";
|
|
39
|
+
public static final String STALLION_PROJECT_ID_IDENTIFIER = "StallionProjectId";
|
|
40
|
+
public static final String STALLION_APP_TOKEN_IDENTIFIER = "StallionAppToken";
|
|
41
|
+
public static final String STALLION_APP_TOKEN_KEY = "x-app-token";
|
|
42
|
+
public static final String STALLION_SDK_TOKEN_KEY = "x-sdk-access-token";
|
|
43
|
+
public static final String STALLION_DEVICE_ID_KEY = "uid";
|
|
44
|
+
public static final String LAST_ROLLED_BACK_RELEASE_HASH_KEY = "LAST_ROLLED_BACK_RELEASE_HASH";
|
|
45
|
+
|
|
46
|
+
public static final String NEW_RELEASE_HASH_ID = "stallionNewReleaseHash";
|
|
47
|
+
public static final String NEW_RELEASE_URL_ID = "stallionNewReleaseUrl";
|
|
48
|
+
public static final String UNIQUE_ID_IDENTIFIER = "stallionDeviceId";
|
|
49
|
+
|
|
50
|
+
public static enum SwitchState {
|
|
51
|
+
PROD,
|
|
52
|
+
STAGE
|
|
53
|
+
}
|
|
54
|
+
public static final String STALLION_NATIVE_EVENT_NAME = "STALLION_NATIVE_EVENT";
|
|
55
|
+
public enum NativeEventTypesProd {
|
|
56
|
+
DOWNLOAD_STARTED_PROD,
|
|
57
|
+
DOWNLOAD_ERROR_PROD,
|
|
58
|
+
DOWNLOAD_PROGRESS_PROD,
|
|
59
|
+
DOWNLOAD_COMPLETE_PROD,
|
|
60
|
+
SYNC_ERROR_PROD,
|
|
61
|
+
ROLLED_BACK_PROD,
|
|
62
|
+
INSTALLED_PROD,
|
|
63
|
+
STABILIZED_PROD,
|
|
64
|
+
EXCEPTION_PROD,
|
|
65
|
+
AUTO_ROLLED_BACK_PROD
|
|
66
|
+
}
|
|
67
|
+
public enum NativeEventTypesStage {
|
|
68
|
+
DOWNLOAD_ERROR_STAGE,
|
|
69
|
+
DOWNLOAD_PROGRESS_STAGE,
|
|
70
|
+
DOWNLOAD_COMPLETE_STAGE,
|
|
71
|
+
}
|
|
36
72
|
}
|
|
37
73
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
package com.stallion;
|
|
2
|
+
|
|
3
|
+
import java.io.BufferedInputStream;
|
|
4
|
+
import java.io.BufferedOutputStream;
|
|
5
|
+
import java.io.File;
|
|
6
|
+
import java.io.FileOutputStream;
|
|
7
|
+
import java.io.IOException;
|
|
8
|
+
import java.net.HttpURLConnection;
|
|
9
|
+
import java.net.URL;
|
|
10
|
+
import java.nio.ByteBuffer;
|
|
11
|
+
import java.util.concurrent.ExecutorService;
|
|
12
|
+
import java.util.concurrent.Executors;
|
|
13
|
+
|
|
14
|
+
public class StallionDownloadManager {
|
|
15
|
+
public static void downloadBundle(
|
|
16
|
+
String downloadUrl,
|
|
17
|
+
String downloadDirectory,
|
|
18
|
+
String sdkAccessToken,
|
|
19
|
+
String appAccessToken,
|
|
20
|
+
StallionDownloadCallback stallionDownloadCallback
|
|
21
|
+
) {
|
|
22
|
+
ExecutorService executor = Executors.newSingleThreadExecutor();
|
|
23
|
+
|
|
24
|
+
executor.execute(() -> {
|
|
25
|
+
|
|
26
|
+
FileOutputStream fout = null;
|
|
27
|
+
BufferedOutputStream bout = null;
|
|
28
|
+
BufferedInputStream inputStream = null;
|
|
29
|
+
HttpURLConnection connection = null;
|
|
30
|
+
File downloadedZip = null;
|
|
31
|
+
boolean isZip = false;
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
int DOWNLOAD_BUFFER_SIZE = StallionConstants.DOWNLOAD_BUFFER_SIZE;
|
|
35
|
+
URL url = new URL(downloadUrl);
|
|
36
|
+
connection = (HttpURLConnection) url.openConnection();
|
|
37
|
+
connection.setRequestMethod( "GET" );
|
|
38
|
+
if(!sdkAccessToken.isEmpty()) {
|
|
39
|
+
connection.setRequestProperty("x-sdk-access-token", sdkAccessToken);
|
|
40
|
+
}
|
|
41
|
+
if(!appAccessToken.isEmpty()) {
|
|
42
|
+
connection.setRequestProperty("x-app-token", appAccessToken);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
connection.setDoInput(true);
|
|
46
|
+
|
|
47
|
+
connection.connect();
|
|
48
|
+
inputStream = new BufferedInputStream(connection.getInputStream());
|
|
49
|
+
File downloadFolder = new File(downloadDirectory);
|
|
50
|
+
if(downloadFolder.exists()) {
|
|
51
|
+
StallionFileUtil.deleteFileOrFolderSilently(downloadFolder);
|
|
52
|
+
}
|
|
53
|
+
downloadFolder.getParentFile().mkdirs();
|
|
54
|
+
|
|
55
|
+
downloadedZip = new File(downloadFolder, StallionConstants.ZIP_FILE_NAME);
|
|
56
|
+
downloadedZip.getParentFile().mkdirs();
|
|
57
|
+
|
|
58
|
+
fout = new FileOutputStream(downloadedZip, false);
|
|
59
|
+
bout = new BufferedOutputStream(fout, DOWNLOAD_BUFFER_SIZE);
|
|
60
|
+
byte[] data = new byte[DOWNLOAD_BUFFER_SIZE];
|
|
61
|
+
byte[] header = new byte[4];
|
|
62
|
+
|
|
63
|
+
long totalBytes = connection.getContentLength();
|
|
64
|
+
long receivedBytes = 0;
|
|
65
|
+
int numBytesRead;
|
|
66
|
+
double prevDownloadFraction = 0;
|
|
67
|
+
double progressEventThreshold = 0.1;
|
|
68
|
+
while ((numBytesRead = inputStream.read(data, 0, DOWNLOAD_BUFFER_SIZE)) >= 0) {
|
|
69
|
+
if (receivedBytes < 4) {
|
|
70
|
+
for (int i = 0; i < numBytesRead; i++) {
|
|
71
|
+
int headerOffset = (int) (receivedBytes) + i;
|
|
72
|
+
if (headerOffset >= 4) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
header[headerOffset] = data[i];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
receivedBytes += numBytesRead;
|
|
80
|
+
bout.write(data, 0, numBytesRead);
|
|
81
|
+
double currentDownloadFraction = (double) receivedBytes / (double) totalBytes;
|
|
82
|
+
if(currentDownloadFraction - prevDownloadFraction > progressEventThreshold) {
|
|
83
|
+
prevDownloadFraction = currentDownloadFraction;
|
|
84
|
+
stallionDownloadCallback.onProgress(currentDownloadFraction);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
isZip = ByteBuffer.wrap(header).getInt() == 0x504b0304;
|
|
89
|
+
} catch (Exception e) {
|
|
90
|
+
stallionDownloadCallback.onReject(StallionConstants.DOWNLOAD_ERROR_PREFIX, StallionConstants.DOWNLOAD_API_ERROR_MESSAGE);
|
|
91
|
+
} finally {
|
|
92
|
+
try {
|
|
93
|
+
if (bout != null) bout.close();
|
|
94
|
+
if (fout != null) fout.close();
|
|
95
|
+
if (inputStream != null) inputStream.close();
|
|
96
|
+
if (connection != null) connection.disconnect();
|
|
97
|
+
} catch (IOException e) {
|
|
98
|
+
stallionDownloadCallback.onReject(StallionConstants.DOWNLOAD_ERROR_PREFIX, StallionConstants.DOWNLOAD_API_ERROR_MESSAGE);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!isZip) {
|
|
103
|
+
stallionDownloadCallback.onReject(StallionConstants.DOWNLOAD_ERROR_PREFIX, "Not a zip file");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
StallionFileUtil.unzipFile(downloadedZip.getAbsolutePath(), downloadDirectory);
|
|
109
|
+
stallionDownloadCallback.onSuccess(StallionConstants.DOWNLOAD_SUCCESS_MESSAGE);
|
|
110
|
+
} catch (Exception e) {
|
|
111
|
+
stallionDownloadCallback.onReject(StallionConstants.DOWNLOAD_ERROR_PREFIX, StallionConstants.DOWNLOAD_FILESYSTEM_ERROR_MESSAGE);
|
|
112
|
+
} finally {
|
|
113
|
+
try {
|
|
114
|
+
StallionFileUtil.deleteFileOrFolderSilently(downloadedZip);
|
|
115
|
+
} catch (Exception e) {
|
|
116
|
+
stallionDownloadCallback.onReject(StallionConstants.DOWNLOAD_ERROR_PREFIX, StallionConstants.DOWNLOAD_DELETE_ERROR);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
package com.stallion;
|
|
2
2
|
|
|
3
3
|
import android.app.Activity;
|
|
4
|
-
import android.content.Context;
|
|
5
4
|
import android.content.Intent;
|
|
6
5
|
import android.util.Log;
|
|
7
6
|
|
|
7
|
+
import com.facebook.react.bridge.Arguments;
|
|
8
8
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
9
|
+
import com.facebook.react.bridge.WritableMap;
|
|
9
10
|
|
|
10
11
|
public class StallionErrorBoundary {
|
|
11
12
|
public static Thread.UncaughtExceptionHandler _androidUncaughtExceptionHandler;
|
|
12
13
|
public static Thread _exceptionThread;
|
|
13
14
|
public static Throwable _exceptionThrowable;
|
|
14
|
-
|
|
15
15
|
public static ReactApplicationContext _currentContext;
|
|
16
|
+
|
|
16
17
|
public static void initErrorBoundary(ReactApplicationContext currentContext) {
|
|
17
18
|
_androidUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
|
|
18
19
|
_currentContext = currentContext;
|
|
19
20
|
}
|
|
21
|
+
|
|
20
22
|
public static void toggleExceptionHandler(Boolean shouldEnableErrorHandler) {
|
|
21
23
|
if(shouldEnableErrorHandler) {
|
|
22
24
|
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
|
|
@@ -24,8 +26,30 @@ public class StallionErrorBoundary {
|
|
|
24
26
|
_exceptionThrowable = throwable;
|
|
25
27
|
String stackTraceString = Log.getStackTraceString(throwable);
|
|
26
28
|
StallionStorage stallionStorage = StallionStorage.getInstance();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
String switchState = stallionStorage.get(StallionConstants.STALLION_SWITCH_STATE_IDENTIFIER);
|
|
30
|
+
|
|
31
|
+
if(switchState.equals(StallionConstants.SwitchState.PROD.toString())) {
|
|
32
|
+
String currentProdSlot = stallionStorage.get(StallionConstants.CURRENT_PROD_SLOT_KEY);
|
|
33
|
+
boolean isAutoRollback = !stallionStorage.getIsMounted();
|
|
34
|
+
if(!currentProdSlot.equals(StallionConstants.DEFAULT_FOLDER_SLOT)) {
|
|
35
|
+
String currentHash = stallionStorage.get(StallionConstants.PROD_DIRECTORY + currentProdSlot);
|
|
36
|
+
WritableMap exceptionErrorPayload = Arguments.createMap();
|
|
37
|
+
exceptionErrorPayload.putString("error", stackTraceString);
|
|
38
|
+
exceptionErrorPayload.putString("releaseHash", currentHash);
|
|
39
|
+
exceptionErrorPayload.putString("isAutoRollback", Boolean.toString(isAutoRollback));
|
|
40
|
+
StallionEventEmitter.cacheEvent(
|
|
41
|
+
StallionEventEmitter.getEventPayload(
|
|
42
|
+
StallionConstants.NativeEventTypesProd.EXCEPTION_PROD.toString(),
|
|
43
|
+
exceptionErrorPayload
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
if(isAutoRollback) {
|
|
48
|
+
StallionRollbackManager.rollbackProd(true);
|
|
49
|
+
}
|
|
50
|
+
continueExceptionFlow();
|
|
51
|
+
} else if(switchState.equals(StallionConstants.SwitchState.STAGE.toString())) {
|
|
52
|
+
StallionRollbackManager.rollbackStage();
|
|
29
53
|
Activity currentActivity = _currentContext.getCurrentActivity();
|
|
30
54
|
if(currentActivity != null) {
|
|
31
55
|
Intent myIntent = new Intent(currentActivity, StallionDefaultErrorActivity.class);
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
package com.stallion;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments;
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
5
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
6
|
+
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
7
|
+
import com.facebook.react.bridge.WritableMap;
|
|
8
|
+
import com.facebook.react.bridge.WritableNativeMap;
|
|
9
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
10
|
+
|
|
11
|
+
import org.json.JSONException;
|
|
12
|
+
import org.json.JSONObject;
|
|
13
|
+
|
|
14
|
+
import java.util.ArrayList;
|
|
15
|
+
import java.util.Iterator;
|
|
16
|
+
import java.util.Objects;
|
|
17
|
+
|
|
18
|
+
public class StallionEventEmitter {
|
|
19
|
+
private static ArrayList<WritableMap> pendingEvents = new ArrayList<WritableMap>();
|
|
20
|
+
private static final String CACHE_EVENTS_KEY = "cached_pending_events";
|
|
21
|
+
|
|
22
|
+
public static void triggerPendingEvents() {
|
|
23
|
+
loadCachedEvents();
|
|
24
|
+
for(WritableMap pendingEvent : pendingEvents) {
|
|
25
|
+
triggerEvent(pendingEvent);
|
|
26
|
+
}
|
|
27
|
+
pendingEvents.clear();
|
|
28
|
+
clearCachedEvents();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public static void sendEvent(WritableMap payload) {
|
|
32
|
+
if(StallionStorage.getInstance().getIsMounted()) {
|
|
33
|
+
triggerEvent(payload);
|
|
34
|
+
} else {
|
|
35
|
+
pendingEvents.add(payload);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private static void triggerEvent(WritableMap payload) {
|
|
40
|
+
ReactApplicationContext reactContext = (ReactApplicationContext) StallionStorage.getInstance().mContext;
|
|
41
|
+
DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
|
|
42
|
+
eventEmitter.emit(StallionConstants.STALLION_NATIVE_EVENT_NAME, payload);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public static WritableMap getEventPayload(String eventName, WritableMap eventValue) {
|
|
46
|
+
StallionStorage stallionStorageInstance = StallionStorage.getInstance();
|
|
47
|
+
String stallionAppVersionCache = stallionStorageInstance.get(StallionConstants.STALLION_APP_VERSION_IDENTIFIER);
|
|
48
|
+
WritableMap params = Arguments.createMap();
|
|
49
|
+
eventValue.putString("AppVersion", stallionAppVersionCache);
|
|
50
|
+
params.putString("type", eventName);
|
|
51
|
+
params.putMap("payload", eventValue);
|
|
52
|
+
return params;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public static void cacheEvent(WritableMap payload) {
|
|
56
|
+
try {
|
|
57
|
+
StallionStorage stallionStorage = StallionStorage.getInstance();
|
|
58
|
+
String cachedEventsJson = stallionStorage.get(CACHE_EVENTS_KEY);
|
|
59
|
+
String newEvent = readableMapToString(payload);
|
|
60
|
+
|
|
61
|
+
// Concatenate the new event with existing ones, separated by a delimiter
|
|
62
|
+
String updatedEvents = cachedEventsJson.isEmpty() ? newEvent : cachedEventsJson + "|" + newEvent;
|
|
63
|
+
stallionStorage.set(CACHE_EVENTS_KEY, updatedEvents);
|
|
64
|
+
} catch (JSONException e) {
|
|
65
|
+
e.printStackTrace();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private static void loadCachedEvents() {
|
|
70
|
+
try {
|
|
71
|
+
StallionStorage stallionStorage = StallionStorage.getInstance();
|
|
72
|
+
String cachedEvents = stallionStorage.get(CACHE_EVENTS_KEY);
|
|
73
|
+
|
|
74
|
+
if (!cachedEvents.isEmpty()) {
|
|
75
|
+
String[] eventArray = cachedEvents.split("\\|");
|
|
76
|
+
for (String eventString : eventArray) {
|
|
77
|
+
WritableMap eventMap = stringToWritableMap(eventString);
|
|
78
|
+
pendingEvents.add(eventMap);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
} catch (JSONException e) {
|
|
82
|
+
e.printStackTrace();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private static void clearCachedEvents() {
|
|
87
|
+
StallionStorage stallionStorage = StallionStorage.getInstance();
|
|
88
|
+
stallionStorage.set(CACHE_EVENTS_KEY, "");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Convert WritableMap to String (JSON)
|
|
92
|
+
public static String readableMapToString(ReadableMap map) throws JSONException {
|
|
93
|
+
JSONObject jsonObject = new JSONObject();
|
|
94
|
+
ReadableMapKeySetIterator iterator = map.keySetIterator();
|
|
95
|
+
|
|
96
|
+
while (iterator.hasNextKey()) {
|
|
97
|
+
String key = iterator.nextKey();
|
|
98
|
+
switch (map.getType(key)) {
|
|
99
|
+
case String:
|
|
100
|
+
jsonObject.put(key, map.getString(key));
|
|
101
|
+
break;
|
|
102
|
+
case Map:
|
|
103
|
+
jsonObject.put(key, new JSONObject(readableMapToString(Objects.requireNonNull(map.getMap(key)))));
|
|
104
|
+
break;
|
|
105
|
+
case Boolean:
|
|
106
|
+
jsonObject.put(key, map.getBoolean(key));
|
|
107
|
+
break;
|
|
108
|
+
case Number:
|
|
109
|
+
jsonObject.put(key, map.getDouble(key));
|
|
110
|
+
break;
|
|
111
|
+
case Null:
|
|
112
|
+
jsonObject.put(key, JSONObject.NULL);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return jsonObject.toString();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Convert String (JSON) back to WritableMap
|
|
120
|
+
public static WritableMap stringToWritableMap(String jsonString) throws JSONException {
|
|
121
|
+
JSONObject jsonObject = new JSONObject(jsonString);
|
|
122
|
+
WritableMap map = new WritableNativeMap();
|
|
123
|
+
|
|
124
|
+
Iterator<String> keys = jsonObject.keys();
|
|
125
|
+
while (keys.hasNext()) {
|
|
126
|
+
String key = keys.next();
|
|
127
|
+
Object value = jsonObject.get(key);
|
|
128
|
+
|
|
129
|
+
if (value instanceof JSONObject) {
|
|
130
|
+
map.putMap(key, stringToWritableMap(value.toString()));
|
|
131
|
+
} else if (value instanceof Boolean) {
|
|
132
|
+
map.putBoolean(key, (Boolean) value);
|
|
133
|
+
} else if (value instanceof Number) {
|
|
134
|
+
map.putDouble(key, ((Number) value).doubleValue());
|
|
135
|
+
} else if (value instanceof String) {
|
|
136
|
+
map.putString(key, (String) value);
|
|
137
|
+
} else if (value == JSONObject.NULL) {
|
|
138
|
+
map.putNull(key);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return map;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
}
|