Skip to content

Instantly share code, notes, and snippets.

@naishe
Created August 4, 2020 06:14
Show Gist options
  • Save naishe/6e6eb26db46d4da9b4249b3bde96d072 to your computer and use it in GitHub Desktop.
Save naishe/6e6eb26db46d4da9b4249b3bde96d072 to your computer and use it in GitHub Desktop.
CodePush Integration: UI to switch Versions
import React, {useState} from 'react';
import {StyleSheet, View, Switch, ActivityIndicator} from 'react-native';
import {Text, ThemeProps, ThemeContext} from 'react-native-elements';
import codePush, {LocalPackage} from 'react-native-code-push';
import AsyncStorage from '@react-native-community/async-storage';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {
CODEPUSH_STAGING_DEPLOYMENT_KEY,
CODEPUSH_PRODUCTION_DEPLOYMENT_KEY,
} from '../utils/constants';
const getVersionString = (version: LocalPackage, isBeta = false) =>
version
? `${isBeta ? 'BETA' : 'STABLE'}: ${version.appVersion}/${version.label}`
: 'LOCAL';
const VersionInfo = () => {
const [version, setVersion] = useState<LocalPackage | null>(null);
const [isBetaUser, setIsBetaUser] = useState(false);
const [counter, setCounter] = useState(0);
const [showBetaUserOption, setShowBetaUserOption] = useState(false);
const [isInstalling, setIsInstalling] = useState(false);
const primary = '#68CCE5';
const secondary = '#2b2c6b';
const grey3 = '#999999';
/**
* Check AsyncStorage to determine whether to show the release to beta switch
*/
React.useEffect(() => {
codePush.getUpdateMetadata().then((update) => {
setVersion(update);
});
AsyncStorage.getItem('IS_BETA_USER').then((betaVersionUserValue) => {
if (betaVersionUserValue === 'true') {
setIsBetaUser(true);
setShowBetaUserOption(true);
}
});
}, []);
/**
* Show the option to switch to beta if user taps eight times
*/
const updateCounter = () => {
if (counter > 7) {
setShowBetaUserOption(true);
return;
}
setCounter(counter + 1);
};
/*
* 1. Configure appropriate deployment key when the user toggles between beta and stable releases
* 2. Immediately pull the latest code and apply the appropriate deployment code
*/
const toggleBetaUser = async () => {
const newBetaUserValue = !isBetaUser;
await AsyncStorage.setItem('IS_BETA_USER', `${newBetaUserValue}`);
setIsBetaUser(newBetaUserValue);
setIsInstalling(true);
codePush.sync(
{
deploymentKey: newBetaUserValue
? CODEPUSH_STAGING_DEPLOYMENT_KEY
: CODEPUSH_PRODUCTION_DEPLOYMENT_KEY,
installMode: codePush.InstallMode.IMMEDIATE,
},
async (status: codePush.SyncStatus) => {
if (status === codePush.SyncStatus.UPDATE_INSTALLED) {
const v = await codePush.getUpdateMetadata();
setIsInstalling(false);
setVersion(v);
}
},
);
};
const versionComponent = !version ? (
<ActivityIndicator />
) : (
<Text>{getVersionString(version, isBetaUser)}</Text>
);
// Show just the version as text if the user hasn't enabled the secret UI by clicking it 8 times
if (!showBetaUserOption) {
return (
<TouchableOpacity onPress={updateCounter}>
<View style={[styles.container, {backgroundColor: secondary}]}>
<Text>Version</Text>
{versionComponent}
</View>
</TouchableOpacity>
);
}
// Allow users to change the versions
return (
<View style={styles.betaContainer}>
<Text h4>Welcome to early adopters section.</Text>
<Text>
You can opt-in to be a beta user. However, please be warned that beta
version may be unstable, crash, and may require reinstalling if things
go wrong.
</Text>
<View style={styles.optInToolbar}>
<View style={styles.optIn}>
<Text style={styles.optInText}>Opt-in</Text>
<Switch
trackColor={{false: grey3, true: primary}}
thumbColor={primary}
ios_backgroundColor={grey3}
onValueChange={toggleBetaUser}
value={isBetaUser}
/>
</View>
<View>
{isInstalling ? (
<ActivityIndicator color={primary} />
) : (
versionComponent
)}
</View>
</View>
</View>
);
};
export default VersionInfo;
const styles = StyleSheet.create({
container: {
padding: 10,
flexDirection: 'row',
justifyContent: 'space-between',
shadowColor: '#000000',
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.18,
shadowRadius: 1.0,
elevation: 1,
},
betaContainer: {
padding: 10,
},
optIn: {
flexDirection: 'row',
alignItems: 'center',
},
optInText: {
paddingRight: 10,
},
optInToolbar: {
flexDirection: 'row',
justifyContent: 'space-between',
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment