36
									
								
								Example/expoUsePushy/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,36 @@ | ||||
| # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files | ||||
|  | ||||
| # dependencies | ||||
| node_modules/ | ||||
|  | ||||
| # Expo | ||||
| .expo/ | ||||
| dist/ | ||||
| web-build/ | ||||
| expo-env.d.ts | ||||
|  | ||||
| # Native | ||||
| *.orig.* | ||||
| *.jks | ||||
| *.p8 | ||||
| *.p12 | ||||
| *.key | ||||
| *.mobileprovision | ||||
|  | ||||
| # Metro | ||||
| .metro-health-check* | ||||
|  | ||||
| # debug | ||||
| npm-debug.* | ||||
| yarn-debug.* | ||||
| yarn-error.* | ||||
|  | ||||
| # macOS | ||||
| .DS_Store | ||||
| *.pem | ||||
|  | ||||
| # local env files | ||||
| .env*.local | ||||
|  | ||||
| # typescript | ||||
| *.tsbuildinfo | ||||
							
								
								
									
										221
									
								
								Example/expoUsePushy/App.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,221 @@ | ||||
| /* eslint-disable react/no-unstable-nested-components */ | ||||
| /* eslint-disable react-native/no-inline-styles */ | ||||
| import React, {useState} from 'react'; | ||||
| import {StyleSheet, Text, View, TouchableOpacity, Image} from 'react-native'; | ||||
|  | ||||
| import TestConsole from './TestConsole'; | ||||
|  | ||||
| import _updateConfig from './update.json'; | ||||
| import {PushyProvider, Pushy, usePushy} from 'react-native-update'; | ||||
| const {appKey} = _updateConfig.android; | ||||
|  | ||||
| function Home() { | ||||
|   const { | ||||
|     client, | ||||
|     checkUpdate, | ||||
|     downloadUpdate, | ||||
|     switchVersionLater, | ||||
|     switchVersion, | ||||
|     updateInfo, | ||||
|     packageVersion, | ||||
|     currentHash, | ||||
|     progress: {received, total} = {}, | ||||
|   } = usePushy(); | ||||
|   const [useDefaultAlert, setUseDefaultAlert] = useState(false); | ||||
|   const [showTestConsole, setShowTestConsole] = useState(false); | ||||
|   const [showUpdateBanner, setShowUpdateBanner] = useState(false); | ||||
|   const [showUpdateSnackbar, setShowUpdateSnackbar] = useState(false); | ||||
|   // if (updateInfo) { | ||||
|   //   updateInfo!.name = 'name'; | ||||
|   //   updateInfo!.update = true; | ||||
|   // } | ||||
|   const snackbarVisible = | ||||
|     !useDefaultAlert && showUpdateSnackbar && updateInfo?.update; | ||||
|  | ||||
|   if (showTestConsole) { | ||||
|     return ( | ||||
|       <TestConsole visible={true} onClose={() => setShowTestConsole(false)} /> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <View style={styles.container}> | ||||
|       <Text style={styles.welcome}>欢迎使用Pushy热更新服务</Text> | ||||
|       {/* <Text style={styles.welcome}>😁hdiffFromAPP更新成功!!!</Text> */} | ||||
|       {/* <Text style={styles.welcome}>😁hdiffFromPPk更新成功!!!</Text> */} | ||||
|       <View style={{flexDirection: 'row'}}> | ||||
|         <TouchableOpacity | ||||
|           onPress={() => { | ||||
|             client?.setOptions({ | ||||
|               updateStrategy: !useDefaultAlert ? null : 'alwaysAlert', | ||||
|             }); | ||||
|             setShowUpdateSnackbar(useDefaultAlert); | ||||
|             setUseDefaultAlert(!useDefaultAlert); | ||||
|           }} | ||||
|           style={{ | ||||
|             flexDirection: 'row', | ||||
|             alignItems: 'center', | ||||
|           }}> | ||||
|           <View | ||||
|             style={{ | ||||
|               width: 20, | ||||
|               height: 20, | ||||
|               borderWidth: 1, | ||||
|               borderColor: '#999', | ||||
|               backgroundColor: useDefaultAlert ? 'blue' : 'white', | ||||
|               justifyContent: 'center', | ||||
|               alignItems: 'center', | ||||
|             }}> | ||||
|             {useDefaultAlert && <Text style={{color: 'white'}}>✓</Text>} | ||||
|           </View> | ||||
|           <Text style={{marginLeft: 8}}> | ||||
|             {' '} | ||||
|             {useDefaultAlert ? '当前使用' : '当前不使用'}默认的alert更新提示 | ||||
|           </Text> | ||||
|         </TouchableOpacity> | ||||
|       </View> | ||||
|       <Image | ||||
|         resizeMode={'contain'} | ||||
|         source={require('./assets/shezhi.png')} | ||||
|         style={styles.image} | ||||
|       /> | ||||
|       <Text style={styles.instructions}> | ||||
|         这是版本一 {'\n'} | ||||
|         当前原生包版本号: {packageVersion} | ||||
|         {'\n'} | ||||
|         当前热更新版本Hash: {currentHash || '(空)'} | ||||
|         {'\n'} | ||||
|       </Text> | ||||
|       <Text> | ||||
|         下载进度:{received} / {total} | ||||
|       </Text> | ||||
|       <TouchableOpacity | ||||
|         onPress={() => { | ||||
|           checkUpdate(); | ||||
|           setShowUpdateSnackbar(true); | ||||
|         }}> | ||||
|         <Text style={styles.instructions}>点击这里检查更新</Text> | ||||
|       </TouchableOpacity> | ||||
|  | ||||
|       <TouchableOpacity | ||||
|         testID="testcase" | ||||
|         style={{marginTop: 15}} | ||||
|         onPress={() => { | ||||
|           setShowTestConsole(true); | ||||
|         }}> | ||||
|         <Text style={styles.instructions}> | ||||
|           react-native-update版本:{client?.version} | ||||
|         </Text> | ||||
|       </TouchableOpacity> | ||||
|       {snackbarVisible && ( | ||||
|         <View style={styles.overlay}> | ||||
|           <View | ||||
|             style={{ | ||||
|               width: '100%', | ||||
|               backgroundColor: '#333', | ||||
|               padding: 16, | ||||
|               flexDirection: 'row', | ||||
|               justifyContent: 'space-between', | ||||
|               alignItems: 'center', | ||||
|             }}> | ||||
|             <Text style={{color: 'white'}}> | ||||
|               有新版本({updateInfo.name})可用,是否更新? | ||||
|             </Text> | ||||
|             <View style={{flexDirection: 'row'}}> | ||||
|               <TouchableOpacity | ||||
|                 onPress={() => setShowUpdateSnackbar(false)} | ||||
|                 style={{marginRight: 10}}> | ||||
|                 <Text style={{color: 'white'}}>取消</Text> | ||||
|               </TouchableOpacity> | ||||
|               <TouchableOpacity | ||||
|                 onPress={async () => { | ||||
|                   setShowUpdateSnackbar(false); | ||||
|                   await downloadUpdate(); | ||||
|                   setShowUpdateBanner(true); | ||||
|                 }}> | ||||
|                 <Text style={{color: '#2196F3'}}>更新</Text> | ||||
|               </TouchableOpacity> | ||||
|             </View> | ||||
|           </View> | ||||
|         </View> | ||||
|       )} | ||||
|       {showUpdateBanner && ( | ||||
|         <View style={styles.overlay}> | ||||
|           <View | ||||
|             style={{ | ||||
|               width: '100%', | ||||
|               backgroundColor: '#fff', | ||||
|               padding: 16, | ||||
|               borderBottomWidth: 1, | ||||
|               borderBottomColor: '#eee', | ||||
|             }}> | ||||
|             <View style={{flexDirection: 'row', alignItems: 'center'}}> | ||||
|               <Text>更新已完成,是否立即重启?</Text> | ||||
|             </View> | ||||
|             <View | ||||
|               style={{ | ||||
|                 flexDirection: 'row', | ||||
|                 justifyContent: 'flex-end', | ||||
|                 marginTop: 10, | ||||
|               }}> | ||||
|               <TouchableOpacity | ||||
|                 onPress={() => { | ||||
|                   switchVersionLater(); | ||||
|                   setShowUpdateBanner(false); | ||||
|                 }} | ||||
|                 style={{marginRight: 20}}> | ||||
|                 <Text style={{color: '#2196F3'}}>下次再说</Text> | ||||
|               </TouchableOpacity> | ||||
|               <TouchableOpacity onPress={switchVersion}> | ||||
|                 <Text style={{color: '#2196F3'}}>立即重启</Text> | ||||
|               </TouchableOpacity> | ||||
|             </View> | ||||
|           </View> | ||||
|         </View> | ||||
|       )} | ||||
|     </View> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| const styles = StyleSheet.create({ | ||||
|   overlay: { | ||||
|     position: 'absolute', | ||||
|     top: 0, | ||||
|     left: 0, | ||||
|     right: 0, | ||||
|     bottom: 0, | ||||
|     backgroundColor: 'rgba(0, 0, 0, 0.5)', | ||||
|     justifyContent: 'center', | ||||
|     alignItems: 'center', | ||||
|   }, | ||||
|   container: { | ||||
|     flex: 1, | ||||
|     justifyContent: 'center', | ||||
|     alignItems: 'center', | ||||
|     backgroundColor: '#F5FCFF', | ||||
|   }, | ||||
|   welcome: { | ||||
|     fontSize: 20, | ||||
|     textAlign: 'center', | ||||
|     margin: 10, | ||||
|   }, | ||||
|   instructions: { | ||||
|     textAlign: 'center', | ||||
|     color: '#333333', | ||||
|     marginBottom: 5, | ||||
|   }, | ||||
|   image: {}, | ||||
| }); | ||||
|  | ||||
| const pushyClient = new Pushy({ | ||||
|   appKey, | ||||
|   debug: true, | ||||
| }); | ||||
|  | ||||
| export default function HomeScreen() { | ||||
|   return ( | ||||
|     <PushyProvider client={pushyClient}> | ||||
|       <Home /> | ||||
|     </PushyProvider> | ||||
|   ); | ||||
| } | ||||
							
								
								
									
										274
									
								
								Example/expoUsePushy/TestConsole.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,274 @@ | ||||
| /* eslint-disable react-native/no-inline-styles */ | ||||
| /* eslint-disable react/react-in-jsx-scope */ | ||||
| import {useCallback, useMemo, useState} from 'react'; | ||||
| import { | ||||
|   ActivityIndicator, | ||||
|   TextInput, | ||||
|   Button, | ||||
|   StyleSheet, | ||||
|   SafeAreaView, | ||||
|   Text, | ||||
|   View, | ||||
|   TouchableOpacity, | ||||
| } from 'react-native'; | ||||
|  | ||||
| import {PushyModule} from 'react-native-update'; | ||||
| const Hash = '9D5CE6EBA420717BE7E7D308B11F8207681B066C951D68F3994D19828F342474'; | ||||
| const UUID = '00000000-0000-0000-0000-000000000000'; | ||||
| const DownloadUrl = 'https://localhost:3000/diff.ppk-patch'; | ||||
| const AppPatchDownloadUrl = 'https://github.com/bozaigao/test_pushy_server/raw/refs/heads/main/hdiff.app-patch'; | ||||
| const AppPatchHash = 'f5ba92c7c04250d4b8a446c8267ef459'; | ||||
| const PPKDownloadUrl = 'https://github.com/bozaigao/test_pushy_server/raw/refs/heads/main/hdiff.ppk-patch'; | ||||
| const PPKPatchHash = '6b3d26b7d868d1f67aedadb7f0b342d9'; | ||||
| const OriginHash = 'f5ba92c7c04250d4b8a446c8267ef459'; | ||||
|  | ||||
|  | ||||
| const CustomDialog = ({title, visible, onConfirm}) => { | ||||
|   if (!visible) { | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <View style={styles.overlay}> | ||||
|       <View style={styles.dialog}> | ||||
|         <Text style={styles.title}>{title}</Text> | ||||
|         <TouchableOpacity | ||||
|           testID="done" | ||||
|           style={styles.button} | ||||
|           onPress={onConfirm}> | ||||
|           <Text style={styles.buttonText}>确认</Text> | ||||
|         </TouchableOpacity> | ||||
|       </View> | ||||
|     </View> | ||||
|   ); | ||||
| }; | ||||
| export default function TestConsole({visible, onClose}) { | ||||
|   const [text, setText] = useState(''); | ||||
|   const [running, setRunning] = useState(false); | ||||
|   const [options, setOptions] = useState(); | ||||
|   const [alertVisible, setAlertVisible] = useState(false); | ||||
|   const [alertMsg, setAlertMsg] = useState(''); | ||||
|   const NativeTestMethod = useMemo(() => { | ||||
|     return [ | ||||
|       { | ||||
|         name: 'setLocalHashInfo', | ||||
|         invoke: () => { | ||||
|           setText( | ||||
|             `setLocalHashInfo\n${Hash}\n{\"version\":\"1.0.0\",\"size\":\"19M\"}`, | ||||
|           ); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'getLocalHashInfo', | ||||
|         invoke: () => { | ||||
|           setText(`getLocalHashInfo\n${Hash}`); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'setUuid', | ||||
|         invoke: () => { | ||||
|           setText(`setUuid\n${UUID}`); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'reloadUpdate', | ||||
|         invoke: () => { | ||||
|           setText('reloadUpdate'); | ||||
|           setOptions({hash: Hash}); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'setNeedUpdateForApp', | ||||
|         invoke: () => { | ||||
|           setText('setNeedUpdate'); | ||||
|           setOptions({hash: AppPatchHash}); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'setNeedUpdateForPPK', | ||||
|         invoke: () => { | ||||
|           setText('setNeedUpdate'); | ||||
|           setOptions({hash: PPKPatchHash}); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'markSuccess', | ||||
|         invoke: () => { | ||||
|           setText('markSuccess'); | ||||
|           setOptions(undefined); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'downloadPatchFromPpk', | ||||
|         invoke: () => { | ||||
|           setText('downloadPatchFromPpk'); | ||||
|           setOptions({updateUrl: PPKDownloadUrl, hash: PPKPatchHash, originHash: OriginHash}); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'downloadPatchFromPackage', | ||||
|         invoke: () => { | ||||
|           setText('downloadPatchFromPackage'); | ||||
|           setOptions({updateUrl: AppPatchDownloadUrl, hash: AppPatchHash}); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'downloadFullUpdate', | ||||
|         invoke: () => { | ||||
|           setText('downloadFullUpdate'); | ||||
|           setOptions({updateUrl: DownloadUrl, hash: Hash}); | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         name: 'downloadAndInstallApk', | ||||
|         invoke: () => { | ||||
|           setText('downloadAndInstallApk'); | ||||
|           setOptions({url: DownloadUrl, target: Hash, hash: Hash}); | ||||
|         }, | ||||
|       }, | ||||
|     ]; | ||||
|   }, []); | ||||
|  | ||||
|   const renderTestView = useCallback(() => { | ||||
|     const views = []; | ||||
|     for (let i = 0; i < NativeTestMethod.length; i++) { | ||||
|       views.push( | ||||
|         <TouchableOpacity | ||||
|           key={i} | ||||
|           testID={NativeTestMethod[i].name} | ||||
|           onPress={() => { | ||||
|             NativeTestMethod[i].invoke(); | ||||
|           }}> | ||||
|           <Text>{NativeTestMethod[i].name}</Text> | ||||
|         </TouchableOpacity>, | ||||
|       ); | ||||
|     } | ||||
|     return <View>{views}</View>; | ||||
|   }, [NativeTestMethod]); | ||||
|   if (!visible) { | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <SafeAreaView style={{flex: 1, padding: 10}}> | ||||
|       <View | ||||
|         style={{ | ||||
|           flexDirection: 'row', | ||||
|           alignItems: 'center', | ||||
|           justifyContent: 'space-between', | ||||
|           padding: 10, | ||||
|         }}> | ||||
|         <Text>调试Pushy方法(方法名,参数,值换行)</Text> | ||||
|         <Button title="关闭" onPress={() => onClose()} /> | ||||
|       </View> | ||||
|       <TextInput | ||||
|         autoCorrect={false} | ||||
|         autoCapitalize="none" | ||||
|         style={{ | ||||
|           borderWidth: StyleSheet.hairlineWidth * 4, | ||||
|           borderColor: 'black', | ||||
|           height: '30%', | ||||
|           marginTop: 20, | ||||
|           marginBottom: 20, | ||||
|           padding: 10, | ||||
|           fontSize: 20, | ||||
|         }} | ||||
|         textAlignVertical="top" | ||||
|         multiline={true} | ||||
|         value={text} | ||||
|         onChangeText={setText} | ||||
|       /> | ||||
|       {running && <ActivityIndicator />} | ||||
|       <TouchableOpacity | ||||
|         style={{ | ||||
|           backgroundColor: 'rgb(0,140,237)', | ||||
|           justifyContent: 'center', | ||||
|           alignItems: 'center', | ||||
|           paddingTop: 10, | ||||
|           paddingBottom: 10, | ||||
|           marginBottom: 5, | ||||
|         }} | ||||
|         testID="submit" | ||||
|         onPress={async () => { | ||||
|           setRunning(true); | ||||
|           try { | ||||
|             const inputs = text.split('\n'); | ||||
|             const methodName = inputs[0]; | ||||
|             let params = []; | ||||
|             if (inputs.length === 1) { | ||||
|               if (options) { | ||||
|                 await PushyModule[methodName](options); | ||||
|               } else { | ||||
|                 await PushyModule[methodName](); | ||||
|               } | ||||
|             } else { | ||||
|               if (inputs.length === 2) { | ||||
|                 params = [inputs[1]]; | ||||
|               } else { | ||||
|                 params = [inputs[1], inputs[2]]; | ||||
|                 console.log({inputs, params}); | ||||
|               } | ||||
|               await PushyModule[methodName](...params); | ||||
|             } | ||||
|             setAlertVisible(true); | ||||
|             setAlertMsg('done'); | ||||
|           } catch (e) { | ||||
|             setAlertVisible(true); | ||||
|             setAlertMsg(e.message); | ||||
|           } | ||||
|           setRunning(false); | ||||
|         }}> | ||||
|         <Text style={{color: 'white'}}>执行</Text> | ||||
|       </TouchableOpacity> | ||||
|       <Button title="重置" onPress={() => setText('')} /> | ||||
|       {renderTestView()} | ||||
|       <CustomDialog | ||||
|         title={alertMsg} | ||||
|         visible={alertVisible} | ||||
|         onConfirm={() => { | ||||
|           setAlertVisible(false); | ||||
|         }} | ||||
|       /> | ||||
|     </SafeAreaView> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| const styles = StyleSheet.create({ | ||||
|   container: { | ||||
|     flex: 1, | ||||
|     justifyContent: 'center', | ||||
|     alignItems: 'center', | ||||
|   }, | ||||
|   overlay: { | ||||
|     position: 'absolute', | ||||
|     top: 0, | ||||
|     left: 0, | ||||
|     right: 0, | ||||
|     bottom: 0, | ||||
|     backgroundColor: 'rgba(0, 0, 0, 0.5)', | ||||
|     justifyContent: 'center', | ||||
|     alignItems: 'center', | ||||
|   }, | ||||
|   dialog: { | ||||
|     backgroundColor: 'white', | ||||
|     borderRadius: 10, | ||||
|     padding: 20, | ||||
|     width: '80%', | ||||
|     alignItems: 'center', | ||||
|   }, | ||||
|   title: { | ||||
|     fontSize: 18, | ||||
|     fontWeight: 'bold', | ||||
|     marginBottom: 20, | ||||
|   }, | ||||
|   button: { | ||||
|     backgroundColor: '#2196F3', | ||||
|     borderRadius: 5, | ||||
|     paddingVertical: 10, | ||||
|     paddingHorizontal: 20, | ||||
|   }, | ||||
|   buttonText: { | ||||
|     color: 'white', | ||||
|     fontWeight: 'bold', | ||||
|   }, | ||||
| }); | ||||
							
								
								
									
										29
									
								
								Example/expoUsePushy/app.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,29 @@ | ||||
| { | ||||
|   "expo": { | ||||
|     "name": "expoUsePushy", | ||||
|     "slug": "expoUsePushy", | ||||
|     "version": "1.0.0", | ||||
|     "orientation": "portrait", | ||||
|     "icon": "./assets/icon.png", | ||||
|     "userInterfaceStyle": "light", | ||||
|     "newArchEnabled": true, | ||||
|     "splash": { | ||||
|       "image": "./assets/splash-icon.png", | ||||
|       "resizeMode": "contain", | ||||
|       "backgroundColor": "#ffffff" | ||||
|     }, | ||||
|     "ios": { | ||||
|       "supportsTablet": true, | ||||
|       "bundleIdentifier": "com.anonymous.expoUsePushy" | ||||
|     }, | ||||
|     "android": { | ||||
|       "adaptiveIcon": { | ||||
|         "foregroundImage": "./assets/adaptive-icon.png", | ||||
|         "backgroundColor": "#ffffff" | ||||
|       } | ||||
|     }, | ||||
|     "web": { | ||||
|       "favicon": "./assets/favicon.png" | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								Example/expoUsePushy/assets/adaptive-icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 17 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Example/expoUsePushy/assets/favicon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Example/expoUsePushy/assets/icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 22 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Example/expoUsePushy/assets/shezhi.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 696 B | 
							
								
								
									
										
											BIN
										
									
								
								Example/expoUsePushy/assets/shezhi@2x.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Example/expoUsePushy/assets/shezhi@3x.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.8 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Example/expoUsePushy/assets/splash-icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 17 KiB | 
							
								
								
									
										8
									
								
								Example/expoUsePushy/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,8 @@ | ||||
| import { registerRootComponent } from 'expo'; | ||||
|  | ||||
| import App from './App'; | ||||
|  | ||||
| // registerRootComponent calls AppRegistry.registerComponent('main', () => App); | ||||
| // It also ensures that whether you load the app in Expo Go or in a native build, | ||||
| // the environment is set up appropriately | ||||
| registerRootComponent(App); | ||||
							
								
								
									
										24
									
								
								Example/expoUsePushy/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,24 @@ | ||||
| { | ||||
|   "name": "expousepushy", | ||||
|   "version": "1.0.0", | ||||
|   "main": "index.js", | ||||
|   "scripts": { | ||||
|     "start": "expo start", | ||||
|     "android": "expo run:android", | ||||
|     "ios": "expo run:ios", | ||||
|     "web": "expo start --web" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "expo": "~52.0.46", | ||||
|     "expo-status-bar": "~2.0.1", | ||||
|     "react": "18.3.1", | ||||
|     "react-native": "0.76.9", | ||||
|     "react-native-update": "^10.28.5" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@babel/core": "^7.25.2", | ||||
|     "@types/react": "~18.3.12", | ||||
|     "typescript": "^5.3.3" | ||||
|   }, | ||||
|   "private": true | ||||
| } | ||||
							
								
								
									
										6
									
								
								Example/expoUsePushy/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|   "extends": "expo/tsconfig.base", | ||||
|   "compilerOptions": { | ||||
|     "strict": true | ||||
|   } | ||||
| } | ||||
							
								
								
									
										14
									
								
								Example/expoUsePushy/update.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,14 @@ | ||||
| { | ||||
|   "ios": { | ||||
|     "appId": 29439, | ||||
|     "appKey": "jNA71vpFHTDpEqeZd9yx87zj" | ||||
|   }, | ||||
|   "android": { | ||||
|     "appId": 29413, | ||||
|     "appKey": "vdZWPXU6eyaPE6Avk96-YvwK" | ||||
|   }, | ||||
|   "harmony": { | ||||
|     "appId": 29140, | ||||
|     "appKey": "JLklGflGIRbY-cMebjQwm1J1" | ||||
|   } | ||||
| } | ||||
 波仔糕
					波仔糕