diff --git a/CodePush.js b/CodePush.js index ff52fce..4804063 100644 --- a/CodePush.js +++ b/CodePush.js @@ -2,6 +2,8 @@ import { AcquisitionManager as Sdk } from "code-push/script/acquisition-sdk"; import { Alert } from "./AlertAdapter"; import requestFetchAdapter from "./request-fetch-adapter"; import { AppState, Platform } from "react-native"; +import RestartManager from "./RestartManager"; +import log from './logging'; let NativeCodePush = require("react-native").NativeModules.CodePush; const PackageMixins = require("./package-mixins")(NativeCodePush); @@ -154,11 +156,6 @@ function getPromisifiedSdk(requestFetchAdapter, config) { return sdk; } -/* Logs messages to console with the [CodePush] prefix */ -function log(message) { - console.log(`[CodePush] ${message}`) -} - // This ensures that notifyApplicationReadyInternal is only called once // in the lifetime of this module instance. const notifyApplicationReady = (() => { @@ -213,10 +210,6 @@ async function tryReportStatus(resumeListener) { } } -function restartApp(onlyIfUpdateIsPending = false) { - NativeCodePush.restartApp(onlyIfUpdateIsPending); -} - var testConfig; // This function is only used for tests. Replaces the default SDK, configuration and native bridge @@ -409,9 +402,11 @@ if (NativeCodePush) { log, notifyAppReady: notifyApplicationReady, notifyApplicationReady, - restartApp, + restartApp: RestartManager.restartApp, setUpTestDependencies, sync, + disallowRestart: RestartManager.disallow, + allowRestart: RestartManager.allow, InstallMode: { IMMEDIATE: NativeCodePush.codePushInstallModeImmediate, // Restart the app immediately ON_NEXT_RESTART: NativeCodePush.codePushInstallModeOnNextRestart, // Don't artificially restart the app. Allow the update to be "picked up" on the next app restart diff --git a/Examples/CodePushDemoApp/crossplatformdemo.js b/Examples/CodePushDemoApp/crossplatformdemo.js index 7111d1c..ff7de19 100644 --- a/Examples/CodePushDemoApp/crossplatformdemo.js +++ b/Examples/CodePushDemoApp/crossplatformdemo.js @@ -19,8 +19,7 @@ let CodePushDemoApp = React.createClass({ try { return await CodePush.sync( { - updateDialog: true, - installMode: CodePush.InstallMode.ON_NEXT_RESUME + installMode: CodePush.InstallMode.IMMEDIATE, }, (syncStatus) => { switch(syncStatus) { @@ -86,7 +85,16 @@ let CodePushDemoApp = React.createClass({ }, getInitialState() { - return { }; + return { restartAllowed: true }; + }, + + toggleAllowRestart() { + if (this.state.restartAllowed) { + CodePush.disallowRestart(); + } else { + CodePush.allowRestart(); + } + this.setState({restartAllowed: !this.state.restartAllowed}); }, render() { @@ -119,6 +127,9 @@ let CodePushDemoApp = React.createClass({ {syncView} {progressView} + ); } diff --git a/RestartManager.js b/RestartManager.js new file mode 100644 index 0000000..0b33c7e --- /dev/null +++ b/RestartManager.js @@ -0,0 +1,45 @@ +let log = require('./logging'); +let NativeCodePush = require("react-native").NativeModules.CodePush; + +const RestartManager = (() => { + let _allowed = true; + let _restartPending = false; + + function restartApp(onlyIfUpdateIsPending = false) { + if (_allowed) { + NativeCodePush.restartApp(onlyIfUpdateIsPending); + log('restaes'); + } else { + log("restart not allowed"); + _restartPending = true; + return true; + } + } + + function allow() { + log("allow restart"); + _allowed = true; + if (_restartPending) { + log("executing pending restart"); + restartApp(true); + } + } + + function disallow() { + log("disallow restart"); + _allowed = false; + } + + function clearPendingRestart() { + _restartPending = false; + } + + return { + allow, + disallow, + restartApp, + clearPendingRestart + }; +})(); + +module.exports = RestartManager; diff --git a/logging.js b/logging.js new file mode 100644 index 0000000..7523589 --- /dev/null +++ b/logging.js @@ -0,0 +1,6 @@ +/* Logs messages to console with the [CodePush] prefix */ +function log(message) { + console.log(`[CodePush] ${message}`); +} + +module.exports = log; diff --git a/package-mixins.js b/package-mixins.js index 0357c41..78127cf 100644 --- a/package-mixins.js +++ b/package-mixins.js @@ -1,5 +1,6 @@ import { AcquisitionManager as Sdk } from "code-push/script/acquisition-sdk"; import { DeviceEventEmitter } from "react-native"; +import RestartManager from "./RestartManager"; // This function is used to augment remote and local // package objects with additional functionality/properties @@ -42,8 +43,9 @@ module.exports = (NativeCodePush) => { await NativeCodePush.installUpdate(this, installMode, minimumBackgroundDuration); updateInstalledCallback && updateInstalledCallback(); if (installMode == NativeCodePush.codePushInstallModeImmediate) { - NativeCodePush.restartApp(false); + RestartManager.restartApp(false); } else { + RestartManager.clearPendingRestart(); localPackage.isPending = true; // Mark the package as pending since it hasn't been applied yet } }, diff --git a/typings/react-native-code-push.d.ts b/typings/react-native-code-push.d.ts index bce50a0..c6f9cc5 100644 --- a/typings/react-native-code-push.d.ts +++ b/typings/react-native-code-push.d.ts @@ -217,7 +217,17 @@ declare namespace CodePush { * Notifies the CodePush runtime that an installed update is considered successful. */ function notifyAppReady(): Promise; - + + /** + * Allow CodePush to restart the app. + */ + function allowRestart(): void; + + /** + * Forbid CodePush to restart the app. + */ + function disallowRestart(): void; + /** * Immediately restarts the app. *