diff --git a/android/src/main/java/com/neoversion/NeoPreference.kt b/android/src/main/java/com/neoversion/NeoPreference.kt index b8ce7cd..5c57883 100644 --- a/android/src/main/java/com/neoversion/NeoPreference.kt +++ b/android/src/main/java/com/neoversion/NeoPreference.kt @@ -1,22 +1,23 @@ package com.neoversion import android.content.Context -import android.content.SharedPreferences -class NeoPreference(private val context: Context) { - private val sharedPreferences: SharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) +class NeoPreference(context: Context) { + private val sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) fun save(key: String, value: String) { val editor = sharedPreferences.edit() editor.putString(key, value) editor.apply() } - fun save(key: String, value: Int) { + + private fun save(key: String, value: Int) { val editor = sharedPreferences.edit() editor.putInt(key, value) editor.apply() } - fun save(key : String, status: Boolean){ - val editor = sharedPreferences.edit() + + fun save(key: String, status: Boolean) { + val editor = sharedPreferences.edit() editor.putBoolean(key, status) editor.apply() } @@ -25,27 +26,45 @@ class NeoPreference(private val context: Context) { return sharedPreferences.getString(key, null) } - fun getValueInt(key: String): Int { + private fun getValueInt(key: String): Int { return sharedPreferences.getInt(key, 0) } - fun getValueBoolean(key: String, defaultValue: Boolean) : Boolean{ + fun getValueBoolean(key: String, defaultValue: Boolean): Boolean { return sharedPreferences.getBoolean(key, defaultValue) } - fun clearSharedPreferences(){ + fun clearSharedPreferences() { val editor = sharedPreferences.edit() editor.clear() editor.apply() } - fun removeValue(key: String){ + fun removeValue(key: String) { val editor = sharedPreferences.edit() editor.remove(key) editor.apply() } + fun saveStalenessDays(day: Int) { + save(STORED_STALENESS_DAYS, day) + } + + fun getStalenessDays(): Int { + return getValueInt(STORED_STALENESS_DAYS) + } + + fun saveSkippedVersion(versionCode: Int) { + save(STORED_SKIPPED_VERSION, versionCode) + } + + fun getSkippedVersion(): Int { + return getValueInt(STORED_SKIPPED_VERSION) + } + companion object { const val PREF_NAME = "neo-version-preference" + const val STORED_STALENESS_DAYS = "storedStalenessDays" + const val STORED_SKIPPED_VERSION = "StoredSkippedVersion" } } diff --git a/android/src/main/java/com/neoversion/NeoVersionModule.kt b/android/src/main/java/com/neoversion/NeoVersionModule.kt index 3b8008c..76eb52d 100644 --- a/android/src/main/java/com/neoversion/NeoVersionModule.kt +++ b/android/src/main/java/com/neoversion/NeoVersionModule.kt @@ -18,6 +18,8 @@ class NeoVersionModule(reactContext: ReactApplicationContext) : private val appUpdateManager = AppUpdateManagerFactory.create(reactContext) private val neoPreference = NeoPreference(reactContext) + private var skippedVersionCode = neoPreference.getSkippedVersion() + private var versionCode: Int? = null @ReactMethod fun getVersionInfo(promise: Promise) { @@ -27,16 +29,18 @@ class NeoVersionModule(reactContext: ReactApplicationContext) : promise.reject("ERROR", err.toString()) } appUpdateInfoTask.addOnSuccessListener { appUpdateInfo -> - val storedStalenessDays = neoPreference.getValueInt("storedStalenessDays") + val storedStalenessDays = neoPreference.getStalenessDays() + versionCode = appUpdateInfo.availableVersionCode() val updateAvailability = appUpdateInfo.updateAvailability() val stalenessDays = appUpdateInfo.clientVersionStalenessDays() ?: 0 - val isUpdateAvailable = updateAvailability == UpdateAvailability.UPDATE_AVAILABLE && stalenessDays > storedStalenessDays + val isUpdateAvailable = + updateAvailability == UpdateAvailability.UPDATE_AVAILABLE && stalenessDays > storedStalenessDays && versionCode!! > skippedVersionCode promise.resolve(isUpdateAvailable) } } @ReactMethod - fun startUpdate(updateType: Int = 0, promise: Promise) { + fun startUpdate(updateType: Int, promise: Promise) { val appUpdateInfoTask = appUpdateManager.appUpdateInfo appUpdateInfoTask.addOnFailureListener { err: Exception -> promise.reject("ERROR", err.toString()) @@ -61,7 +65,12 @@ class NeoVersionModule(reactContext: ReactApplicationContext) : @ReactMethod fun presentNextTime(day: Int) { - neoPreference.save("storedStalenessDays", day) + neoPreference.saveStalenessDays(day) + } + + @ReactMethod + fun skipThisVersion() { + versionCode?.let { neoPreference.saveSkippedVersion(it) } } companion object { diff --git a/example/ios/NeoVersionExample.xcodeproj/project.pbxproj b/example/ios/NeoVersionExample.xcodeproj/project.pbxproj index a1607af..d3efc98 100644 --- a/example/ios/NeoVersionExample.xcodeproj/project.pbxproj +++ b/example/ios/NeoVersionExample.xcodeproj/project.pbxproj @@ -8,12 +8,12 @@ /* Begin PBXBuildFile section */ 00E356F31AD99517003FC87E /* NeoVersionExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* NeoVersionExampleTests.m */; }; - 0C80B921A6F3F58F76C31292 /* libPods-NeoVersionExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-NeoVersionExample.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 7699B88040F8A987B510C191 /* libPods-NeoVersionExample-NeoVersionExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-NeoVersionExample-NeoVersionExampleTests.a */; }; + 28487165A6A7BD3A2F1DC4AC /* libPods-NeoVersionExample-NeoVersionExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0508A15CCC90A38172CD5046 /* libPods-NeoVersionExample-NeoVersionExampleTests.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + C4A0E340EACF0F8DD59858F9 /* libPods-NeoVersionExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 589EC1AC8BB5681357409BDA /* libPods-NeoVersionExample.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -30,19 +30,19 @@ 00E356EE1AD99517003FC87E /* NeoVersionExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NeoVersionExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* NeoVersionExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NeoVersionExampleTests.m; sourceTree = ""; }; + 0508A15CCC90A38172CD5046 /* libPods-NeoVersionExample-NeoVersionExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NeoVersionExample-NeoVersionExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 0FD8EDF1E6DFDE24B88C42E2 /* Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* NeoVersionExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NeoVersionExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = NeoVersionExample/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = NeoVersionExample/AppDelegate.mm; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = NeoVersionExample/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = NeoVersionExample/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = NeoVersionExample/main.m; sourceTree = ""; }; - 19F6CBCC0A4E27FBF8BF4A61 /* libPods-NeoVersionExample-NeoVersionExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NeoVersionExample-NeoVersionExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B4392A12AC88292D35C810B /* Pods-NeoVersionExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeoVersionExample.debug.xcconfig"; path = "Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample.debug.xcconfig"; sourceTree = ""; }; - 5709B34CF0A7D63546082F79 /* Pods-NeoVersionExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeoVersionExample.release.xcconfig"; path = "Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample.release.xcconfig"; sourceTree = ""; }; - 5B7EB9410499542E8C5724F5 /* Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig"; sourceTree = ""; }; - 5DCACB8F33CDC322A6C60F78 /* libPods-NeoVersionExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NeoVersionExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4D1F9D48FDA689CDDEF33DFD /* Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig"; path = "Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig"; sourceTree = ""; }; + 589EC1AC8BB5681357409BDA /* libPods-NeoVersionExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NeoVersionExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = NeoVersionExample/LaunchScreen.storyboard; sourceTree = ""; }; - 89C6BE57DB24E9ADA2F236DE /* Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig"; path = "Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig"; sourceTree = ""; }; + 95FA2384BA5C0BCD98C69683 /* Pods-NeoVersionExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeoVersionExample.release.xcconfig"; path = "Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample.release.xcconfig"; sourceTree = ""; }; + 9DEE802E760FAED189A4A7EE /* Pods-NeoVersionExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NeoVersionExample.debug.xcconfig"; path = "Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample.debug.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -51,7 +51,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7699B88040F8A987B510C191 /* libPods-NeoVersionExample-NeoVersionExampleTests.a in Frameworks */, + 28487165A6A7BD3A2F1DC4AC /* libPods-NeoVersionExample-NeoVersionExampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,7 +59,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C80B921A6F3F58F76C31292 /* libPods-NeoVersionExample.a in Frameworks */, + C4A0E340EACF0F8DD59858F9 /* libPods-NeoVersionExample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -100,8 +100,8 @@ isa = PBXGroup; children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - 5DCACB8F33CDC322A6C60F78 /* libPods-NeoVersionExample.a */, - 19F6CBCC0A4E27FBF8BF4A61 /* libPods-NeoVersionExample-NeoVersionExampleTests.a */, + 589EC1AC8BB5681357409BDA /* libPods-NeoVersionExample.a */, + 0508A15CCC90A38172CD5046 /* libPods-NeoVersionExample-NeoVersionExampleTests.a */, ); name = Frameworks; sourceTree = ""; @@ -140,10 +140,10 @@ BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - 3B4392A12AC88292D35C810B /* Pods-NeoVersionExample.debug.xcconfig */, - 5709B34CF0A7D63546082F79 /* Pods-NeoVersionExample.release.xcconfig */, - 5B7EB9410499542E8C5724F5 /* Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig */, - 89C6BE57DB24E9ADA2F236DE /* Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig */, + 9DEE802E760FAED189A4A7EE /* Pods-NeoVersionExample.debug.xcconfig */, + 95FA2384BA5C0BCD98C69683 /* Pods-NeoVersionExample.release.xcconfig */, + 0FD8EDF1E6DFDE24B88C42E2 /* Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig */, + 4D1F9D48FDA689CDDEF33DFD /* Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -155,12 +155,12 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "NeoVersionExampleTests" */; buildPhases = ( - A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */, + 7403512414FA8BCD24E68E8C /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */, - F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */, + 355E090BBA9810AB0CCBD8E6 /* [CP] Embed Pods Frameworks */, + DEEA64AE03FCCA4B05652ED3 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -176,13 +176,13 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "NeoVersionExample" */; buildPhases = ( - C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, + C6A210F430B088E7FDCF04C5 /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */, - E235C05ADACE081382539298 /* [CP] Copy Pods Resources */, + 7C1D32D1257E0D81750AC825 /* [CP] Embed Pods Frameworks */, + 8F4DC20E63C2326C3BDF6FDE /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -265,24 +265,24 @@ shellPath = /bin/sh; shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; - 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { + 355E090BBA9810AB0CCBD8E6 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = { + 7403512414FA8BCD24E68E8C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -304,63 +304,63 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = { + 7C1D32D1257E0D81750AC825 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-NeoVersionExample-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = { + 8F4DC20E63C2326C3BDF6FDE /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample-NeoVersionExampleTests/Pods-NeoVersionExample-NeoVersionExampleTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; - E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = { + C6A210F430B088E7FDCF04C5 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-NeoVersionExample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NeoVersionExample/Pods-NeoVersionExample-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = { + DEEA64AE03FCCA4B05652ED3 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -410,7 +410,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig */; + baseConfigurationReference = 0FD8EDF1E6DFDE24B88C42E2 /* Pods-NeoVersionExample-NeoVersionExampleTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -437,7 +437,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig */; + baseConfigurationReference = 4D1F9D48FDA689CDDEF33DFD /* Pods-NeoVersionExample-NeoVersionExampleTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; @@ -461,7 +461,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-NeoVersionExample.debug.xcconfig */; + baseConfigurationReference = 9DEE802E760FAED189A4A7EE /* Pods-NeoVersionExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -489,7 +489,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-NeoVersionExample.release.xcconfig */; + baseConfigurationReference = 95FA2384BA5C0BCD98C69683 /* Pods-NeoVersionExample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 41c4f1e..faad5bd 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1111,7 +1111,7 @@ PODS: - React-jsi (= 0.73.4) - React-logger (= 0.73.4) - React-perflogger (= 0.73.4) - - ReactNativeNeoVersion (0.1.0): + - ReactNativeNeoVersion (0.3.0): - glog - RCT-Folly (= 2022.05.16.00) - React-Core @@ -1371,7 +1371,7 @@ SPEC CHECKSUMS: React-runtimescheduler: ed48e5faac6751e66ee1261c4bd01643b436f112 React-utils: 6e5ad394416482ae21831050928ae27348f83487 ReactCommon: 840a955d37b7f3358554d819446bffcf624b2522 - ReactNativeNeoVersion: 88b8dd1c128d799073ebca4d3570c1d29ca9e513 + ReactNativeNeoVersion: dae17c1b295fa22b5e2ca930ce76accfe39ff407 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 Yoga: 1b901a6d6eeba4e8a2e8f308f708691cdb5db312 diff --git a/src/Android/neoVersion.android.ts b/src/Android/neoVersion.android.ts deleted file mode 100644 index 42eaf1c..0000000 --- a/src/Android/neoVersion.android.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NativeModules } from 'react-native'; - -const neoVersion = NativeModules.NeoVersion; - -export function getVersionInfo(): Promise { - return neoVersion.getVersionInfo(); -} - -export function startUpdate(): Promise { - // flexible update by default - return neoVersion.startUpdate(0); -} - -export function presentNextTime(day: number) { - return neoVersion.presentNextTime(day); -} - -export default neoVersion; diff --git a/src/android/alertButton.ts b/src/android/alertButton.ts new file mode 100644 index 0000000..7832b62 --- /dev/null +++ b/src/android/alertButton.ts @@ -0,0 +1,40 @@ +import type { AlertButton } from 'react-native'; +import { startUpdate, presentNextTime, skipThisVersion } from './neoVersion'; + +export const UpdateTypeMap = { + flexible: 0, + immediate: 1, +} as const; + +export type UpdateTypeKey = keyof typeof UpdateTypeMap; +export type UpdateTypeVal = (typeof UpdateTypeMap)[UpdateTypeKey]; + +export const updateButton = (updateType: UpdateTypeKey): AlertButton => { + return { + text: 'Update', + onPress: () => { + startUpdate(updateType); + }, + style: 'default', + }; +}; + +export const skipButton = (): AlertButton => { + return { + text: 'Skip this version', + onPress: () => { + skipThisVersion(); + }, + style: 'default', + }; +}; + +export const nextTimeButton = (day: number): AlertButton => { + return { + text: 'Next Time', + onPress: () => { + presentNextTime(day); + }, + style: 'default', + }; +}; diff --git a/src/android/neoVersion.ts b/src/android/neoVersion.ts new file mode 100644 index 0000000..fc6882b --- /dev/null +++ b/src/android/neoVersion.ts @@ -0,0 +1,26 @@ +import { NativeModules } from 'react-native'; +import { UpdateTypeMap, type UpdateTypeKey } from './alertButton'; + +const neoVersion = NativeModules.NeoVersion; + +export function getVersionInfo(): Promise { + return neoVersion.getVersionInfo(); +} + +// flexible update by default +export async function startUpdate( + updateType: UpdateTypeKey = 'flexible' +): Promise { + const type = UpdateTypeMap[updateType]; + return await neoVersion.startUpdate(type); +} + +export async function presentNextTime(day: number) { + return await neoVersion.presentNextTime(day); +} + +export async function skipThisVersion(): Promise { + return await neoVersion.skipThisVersion(); +} + +export default neoVersion; diff --git a/src/android/rules.ts b/src/android/rules.ts new file mode 100644 index 0000000..bcb7501 --- /dev/null +++ b/src/android/rules.ts @@ -0,0 +1,13 @@ +import type { AlertButton } from 'react-native'; +import { nextTimeButton, skipButton, updateButton } from './alertButton'; +import type { AlertType } from '../types'; + +export const generateAlertButtons = ( + alertType: AlertType, + day: number +): AlertButton[] => { + if (alertType === 'force') return [updateButton('immediate')]; + if (alertType === 'option') + return [updateButton('flexible'), nextTimeButton(day)]; + return [updateButton('flexible'), skipButton(), nextTimeButton(day)]; +}; diff --git a/src/Android/useNeoVersionCheck.android.ts b/src/android/useNeoVersionCheck.ts similarity index 50% rename from src/Android/useNeoVersionCheck.android.ts rename to src/android/useNeoVersionCheck.ts index d8ed2d7..124e663 100644 --- a/src/Android/useNeoVersionCheck.android.ts +++ b/src/android/useNeoVersionCheck.ts @@ -1,40 +1,29 @@ import { useEffect } from 'react'; -import { - getVersionInfo, - presentNextTime, - startUpdate, -} from './neoVersion.android'; +import { getVersionInfo } from './neoVersion'; import { Alert } from 'react-native'; import type { Configuration } from '../types'; +import { generateAlertButtons } from './rules'; export const useNeoVersionCheck = (configuration?: Partial) => { useEffect(() => { const performVersionCheck = async () => { const isUpdateAvailable = await getVersionInfo(); + const freq = configuration?.frequency ?? 7; + const type = configuration?.alertType ?? 'skip'; if (isUpdateAvailable) { Alert.alert( configuration?.title ?? 'Update Available', configuration?.message ?? 'Please update the app to have the best experience', - [ - { - text: 'Update', - onPress: () => { - startUpdate(); - }, - style: 'default', - }, - { - text: 'Next time', - onPress: () => { - presentNextTime(configuration?.frequency ?? 7); - }, - style: 'default', - }, - ] + generateAlertButtons(type, freq) ); } }; performVersionCheck(); - }, [configuration?.frequency, configuration?.message, configuration?.title]); + }, [ + configuration?.alertType, + configuration?.frequency, + configuration?.message, + configuration?.title, + ]); }; diff --git a/src/index.android.ts b/src/index.android.ts index c6d5d62..042620d 100644 --- a/src/index.android.ts +++ b/src/index.android.ts @@ -1 +1 @@ -export { useNeoVersionCheck } from './Android/useNeoVersionCheck.android'; +export { useNeoVersionCheck } from './android/useNeoVersionCheck'; diff --git a/src/index.ios.ts b/src/index.ios.ts index 4865cc4..086a844 100644 --- a/src/index.ios.ts +++ b/src/index.ios.ts @@ -1 +1 @@ -export { useNeoVersionCheck } from './iOS/useNeoVersionCheck.ios'; +export { useNeoVersionCheck } from './ios/useNeoVersionCheck'; diff --git a/src/iOS/alertButton.ts b/src/ios/alertButton.ts similarity index 86% rename from src/iOS/alertButton.ts rename to src/ios/alertButton.ts index 61de3c3..3b68de8 100644 --- a/src/iOS/alertButton.ts +++ b/src/ios/alertButton.ts @@ -1,9 +1,5 @@ import type { AlertButton } from 'react-native'; -import { - launchAppStore, - presentNextTime, - skipThisVersion, -} from './neoVersion.ios'; +import { launchAppStore, presentNextTime, skipThisVersion } from './neoVersion'; export const updateButton = (): AlertButton => { return { diff --git a/src/iOS/neoVersion.ios.ts b/src/ios/neoVersion.ts similarity index 93% rename from src/iOS/neoVersion.ios.ts rename to src/ios/neoVersion.ts index 9e45509..d5ea513 100644 --- a/src/iOS/neoVersion.ios.ts +++ b/src/ios/neoVersion.ts @@ -1,5 +1,5 @@ import { NativeModules } from 'react-native'; -import type { UpdateType } from '../types'; +import type { UpdateType } from './rules'; const neoVersion = NativeModules.NeoVersion; diff --git a/src/iOS/rules.ts b/src/ios/rules.ts similarity index 84% rename from src/iOS/rules.ts rename to src/ios/rules.ts index 2f312a2..50a2e08 100644 --- a/src/iOS/rules.ts +++ b/src/ios/rules.ts @@ -1,6 +1,14 @@ import type { AlertButton } from 'react-native'; import { nextTimeButton, skipButton, updateButton } from './alertButton'; -import { type AlertType, type UpdateType, type Rules } from '../types'; +import { type AlertType } from '../types'; + +export type UpdateType = 'major' | 'minor' | 'patch' | 'unknown'; +export type Frequency = 0 | 1 | 7; + +export type Rules = { + alertType: AlertType; + frequency: Frequency | number; +}; const criticalRules: Rules = { alertType: 'force', diff --git a/src/iOS/useNeoVersionCheck.ios.ts b/src/ios/useNeoVersionCheck.ts similarity index 98% rename from src/iOS/useNeoVersionCheck.ios.ts rename to src/ios/useNeoVersionCheck.ts index 634a904..a6b4e4c 100644 --- a/src/iOS/useNeoVersionCheck.ios.ts +++ b/src/ios/useNeoVersionCheck.ts @@ -2,7 +2,7 @@ import { useEffect } from 'react'; import { Alert } from 'react-native'; import type { Configuration } from '../types'; import { generateAlertButtons, parse, shouldPresentAlert } from './rules'; -import { computeDaysSincePresentation, getVersionInfo } from './neoVersion.ios'; +import { computeDaysSincePresentation, getVersionInfo } from './neoVersion'; export const useNeoVersionCheck = (configuration?: Partial) => { useEffect(() => { diff --git a/src/types.ts b/src/types.ts index 1bbcdb3..a3833fb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,18 +1,4 @@ -export const FrequencyMap = { - immediately: 0, - daily: 1, - weekly: 7, -} as const; - -export type FrequencyKey = keyof typeof FrequencyMap; -export type FrequencyVal = (typeof FrequencyMap)[FrequencyKey]; export type AlertType = 'force' | 'option' | 'skip'; -export type UpdateType = 'major' | 'minor' | 'patch' | 'unknown'; - -export type Rules = { - alertType: AlertType; - frequency: FrequencyVal | number; -}; export type Configuration = { title: string;