react-native-codepush-sdk
Version:
A React Native CodePush SDK for over-the-air updates
231 lines (230 loc) • 10.2 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const react_native_1 = require("react-native");
const CodePushProvider_1 = require("../sdk/CodePushProvider");
const UpdateChecker = () => {
const { currentUpdate, availableUpdate, syncStatus, isChecking, isDownloading, isInstalling, checkForUpdate, syncUpdate, rollback, clearUpdates, } = (0, CodePushProvider_1.useCodePush)();
const getStatusMessage = () => {
if (isChecking)
return 'Checking for updates...';
if (isDownloading)
return 'Downloading update...';
if (isInstalling)
return 'Installing update...';
if (availableUpdate)
return 'Update available!';
return 'App is up to date';
};
const getStatusColor = () => {
if (isChecking || isDownloading || isInstalling)
return '#007bff';
if (availableUpdate)
return '#ffc107';
return '#28a745';
};
const handleRollback = () => {
react_native_1.Alert.alert('Rollback Update', 'Are you sure you want to rollback to the previous version? This will restart the app.', [
{ text: 'Cancel', style: 'cancel' },
{ text: 'Rollback', style: 'destructive', onPress: rollback },
]);
};
const handleClearUpdates = () => {
react_native_1.Alert.alert('Clear Updates', 'This will remove all downloaded updates and reset to the original app version.', [
{ text: 'Cancel', style: 'cancel' },
{ text: 'Clear', style: 'destructive', onPress: clearUpdates },
]);
};
const formatBytes = (bytes) => {
if (bytes === 0)
return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
react_1.default.createElement(react_native_1.View, { style: styles.header },
react_1.default.createElement(react_native_1.Text, { style: styles.title }, "Custom CodePush"),
react_1.default.createElement(react_native_1.Text, { style: styles.subtitle }, "Over-the-Air Updates")),
react_1.default.createElement(react_native_1.View, { style: [styles.statusCard, { borderLeftColor: getStatusColor() }] },
react_1.default.createElement(react_native_1.View, { style: styles.statusHeader },
react_1.default.createElement(react_native_1.Text, { style: [styles.statusText, { color: getStatusColor() }] }, getStatusMessage()),
(isChecking || isDownloading || isInstalling) && (react_1.default.createElement(react_native_1.ActivityIndicator, { size: "small", color: getStatusColor() }))),
(syncStatus === null || syncStatus === void 0 ? void 0 : syncStatus.progress) !== undefined && (react_1.default.createElement(react_native_1.View, { style: styles.progressContainer },
react_1.default.createElement(react_native_1.View, { style: styles.progressBar },
react_1.default.createElement(react_native_1.View, { style: [
styles.progressFill,
{
width: `${syncStatus.progress}%`,
backgroundColor: getStatusColor(),
},
] })),
react_1.default.createElement(react_native_1.Text, { style: styles.progressText },
Math.round(syncStatus.progress),
"%")))),
currentUpdate && (react_1.default.createElement(react_native_1.View, { style: styles.infoCard },
react_1.default.createElement(react_native_1.Text, { style: styles.cardTitle }, "Current Version"),
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
"Label: ",
currentUpdate.label),
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
"Version: ",
currentUpdate.appVersion),
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
"Hash: ",
currentUpdate.packageHash.substring(0, 8),
"..."),
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
"Size: ",
formatBytes(currentUpdate.packageSize)),
currentUpdate.description && (react_1.default.createElement(react_native_1.Text, { style: styles.infoDescription }, currentUpdate.description)))),
availableUpdate && (react_1.default.createElement(react_native_1.View, { style: styles.infoCard },
react_1.default.createElement(react_native_1.Text, { style: styles.cardTitle }, "Available Update"),
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
"Label: ",
availableUpdate.label),
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
"Version: ",
availableUpdate.appVersion),
react_1.default.createElement(react_native_1.Text, { style: styles.infoText },
"Size: ",
formatBytes(availableUpdate.packageSize)),
react_1.default.createElement(react_native_1.Text, { style: [
styles.infoText,
{ color: availableUpdate.isMandatory ? '#dc3545' : '#28a745' }
] }, availableUpdate.isMandatory ? 'Mandatory Update' : 'Optional Update'),
availableUpdate.description && (react_1.default.createElement(react_native_1.Text, { style: styles.infoDescription }, availableUpdate.description)))),
react_1.default.createElement(react_native_1.View, { style: styles.buttonContainer },
react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, styles.primaryButton], onPress: checkForUpdate, disabled: isChecking },
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, "Check for Updates")),
availableUpdate && (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, styles.successButton], onPress: syncUpdate, disabled: isDownloading || isInstalling },
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, availableUpdate.isMandatory ? 'Install Now (Required)' : 'Install Update'))),
currentUpdate && (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, styles.warningButton], onPress: handleRollback, disabled: isDownloading || isInstalling },
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, "Rollback"))),
react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, styles.dangerButton], onPress: handleClearUpdates, disabled: isDownloading || isInstalling },
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, "Clear All Updates")))));
};
const styles = react_native_1.StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f8f9fa',
},
header: {
alignItems: 'center',
marginBottom: 30,
},
title: {
fontSize: 28,
fontWeight: 'bold',
color: '#212529',
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: '#6c757d',
},
statusCard: {
backgroundColor: '#ffffff',
borderRadius: 8,
padding: 20,
marginBottom: 20,
borderLeftWidth: 4,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
statusHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
statusText: {
fontSize: 18,
fontWeight: '600',
},
progressContainer: {
marginTop: 15,
flexDirection: 'row',
alignItems: 'center',
},
progressBar: {
flex: 1,
height: 8,
backgroundColor: '#e9ecef',
borderRadius: 4,
marginRight: 10,
},
progressFill: {
height: '100%',
borderRadius: 4,
},
progressText: {
fontSize: 14,
fontWeight: '500',
color: '#495057',
minWidth: 40,
},
infoCard: {
backgroundColor: '#ffffff',
borderRadius: 8,
padding: 16,
marginBottom: 16,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
elevation: 2,
},
cardTitle: {
fontSize: 18,
fontWeight: '600',
color: '#212529',
marginBottom: 12,
},
infoText: {
fontSize: 14,
color: '#495057',
marginBottom: 4,
},
infoDescription: {
fontSize: 14,
color: '#6c757d',
marginTop: 8,
fontStyle: 'italic',
},
buttonContainer: {
marginTop: 20,
},
button: {
paddingVertical: 12,
paddingHorizontal: 20,
borderRadius: 8,
marginBottom: 12,
alignItems: 'center',
},
primaryButton: {
backgroundColor: '#007bff',
},
successButton: {
backgroundColor: '#28a745',
},
warningButton: {
backgroundColor: '#ffc107',
},
dangerButton: {
backgroundColor: '#dc3545',
},
buttonText: {
color: '#ffffff',
fontSize: 16,
fontWeight: '600',
},
});
exports.default = UpdateChecker;