about.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. import React, {Component} from 'react';
  2. import {
  3. Image,
  4. Text,
  5. View,
  6. TouchableOpacity,
  7. Alert,
  8. SafeAreaView,
  9. ScrollView,
  10. Platform,
  11. Linking,
  12. StyleSheet,
  13. } from 'react-native';
  14. import {
  15. isFirstTime,
  16. isRolledBack,
  17. packageVersion,
  18. checkUpdate,
  19. downloadUpdate,
  20. switchVersion,
  21. switchVersionLater,
  22. markSuccess,
  23. downloadAndInstallApk,
  24. } from 'react-native-update';
  25. import {WhiteSpace, Progress, Modal, Provider} from '@ant-design/react-native';
  26. import public_css from '../../source/css/public_css';
  27. import _updateConfig from '../../update.json';
  28. const {appKey} = _updateConfig[Platform.OS];
  29. export default class about extends Component {
  30. constructor(props) {
  31. super(props);
  32. this.props.navigation.dangerouslyGetParent().setOptions({
  33. tabBarVisible: false,
  34. });
  35. this.state = {
  36. received: 0,
  37. total: 0,
  38. proportion: 0,
  39. isDownload: false,
  40. };
  41. }
  42. render() {
  43. return (
  44. <Provider>
  45. <SafeAreaView style={public_css.body}>
  46. <ScrollView>
  47. <View style={styles.aboutView}>
  48. <View style={styles.blankView} />
  49. <View>
  50. <Image
  51. source={require('../../source/img/personal/invoice.png')}
  52. />
  53. </View>
  54. <View style={styles.aboutViewDistance}>
  55. <Text style={styles.aboutViewText}>云票在线</Text>
  56. </View>
  57. <View style={styles.aboutViewDistance}>
  58. <Text style={styles.aboutVersionText}>
  59. 版本号:{packageVersion}
  60. </Text>
  61. </View>
  62. </View>
  63. <Modal
  64. title="更新进度"
  65. transparent
  66. maskClosable
  67. visible={this.state.isDownload}
  68. closable={false}>
  69. <View style={styles.speedView1}>
  70. <View style={styles.speedView2}>
  71. <View style={styles.speedView3}>
  72. <Progress percent={this.state.proportion} />
  73. </View>
  74. <Text>{this.state.proportion}%</Text>
  75. </View>
  76. </View>
  77. </Modal>
  78. </ScrollView>
  79. <View style={styles.checkUpdateView}>
  80. <TouchableOpacity onPress={this.checkUpdate}>
  81. <Text style={styles.checkUpdateText}>检查更新</Text>
  82. </TouchableOpacity>
  83. </View>
  84. <WhiteSpace />
  85. </SafeAreaView>
  86. </Provider>
  87. );
  88. }
  89. componentDidMount() {
  90. if (isFirstTime) {
  91. // 必须调用此更新成功标记方法
  92. // 否则默认更新失败,下一次启动会自动回滚
  93. markSuccess();
  94. console.log('更新完成');
  95. } else if (isRolledBack) {
  96. console.log('刚刚更新失败了,版本被回滚.');
  97. }
  98. }
  99. // 下载更新
  100. doUpdate = async (info) => {
  101. try {
  102. this.setState({
  103. isDownload: true,
  104. });
  105. const hash = await downloadUpdate(info, {
  106. onDownloadProgress: ({received, total}) => {
  107. if (received !== '' && received !== null) {
  108. if (total !== '' && total !== null) {
  109. let proportion =
  110. (parseInt(received, 10) / parseInt(total, 10)) * 100;
  111. this.setState({
  112. proportion: proportion,
  113. });
  114. }
  115. }
  116. this.setState({
  117. received,
  118. total,
  119. });
  120. },
  121. });
  122. this.setState({
  123. isDownload: false,
  124. });
  125. Alert.alert('提示', '下载完毕,是否重启应用?', [
  126. {
  127. text: '是',
  128. onPress: () => {
  129. switchVersion(hash);
  130. },
  131. },
  132. {text: '否'},
  133. {
  134. text: '下次启动时',
  135. onPress: () => {
  136. switchVersionLater(hash);
  137. },
  138. },
  139. ]);
  140. } catch (err) {
  141. Alert.alert('更新失败', err.message);
  142. }
  143. };
  144. // 检查更新
  145. checkUpdate = async () => {
  146. if (__DEV__) {
  147. // 开发模式不支持热更新,跳过检查
  148. return;
  149. }
  150. let info;
  151. try {
  152. info = await checkUpdate(appKey);
  153. } catch (err) {
  154. Alert.alert('更新检查失败', err.message);
  155. return;
  156. }
  157. if (info.expired) {
  158. Alert.alert('提示', '您的应用版本已更新,点击确定下载安装新版本', [
  159. {
  160. text: '确定',
  161. onPress: () => {
  162. if (info.downloadUrl) {
  163. // apk可直接下载安装
  164. if (
  165. Platform.OS === 'android' &&
  166. info.downloadUrl.endsWith('.apk')
  167. ) {
  168. downloadAndInstallApk({
  169. url: info.downloadUrl,
  170. onDownloadProgress: ({received, total}) => {
  171. if (received !== '' && received !== null) {
  172. if (total !== '' && total !== null) {
  173. let proportion =
  174. (parseInt(received) / parseInt(total)) * 100;
  175. this.setState({
  176. proportion: parseInt(proportion),
  177. });
  178. if (parseInt(proportion) >= 100) {
  179. this.setState({
  180. isDownload: false,
  181. });
  182. }
  183. }
  184. }
  185. this.setState({
  186. received,
  187. total,
  188. });
  189. },
  190. });
  191. } else {
  192. Linking.openURL(info.downloadUrl);
  193. }
  194. }
  195. },
  196. },
  197. ]);
  198. } else if (info.upToDate) {
  199. Alert.alert('提示', '您的应用版本已是最新.');
  200. } else {
  201. Alert.alert(
  202. '提示',
  203. '检查到新的版本' + info.name + ',是否下载?\n' + info.description,
  204. [
  205. {
  206. text: '是',
  207. onPress: () => {
  208. this.doUpdate(info);
  209. },
  210. },
  211. {text: '否'},
  212. ],
  213. );
  214. }
  215. };
  216. }
  217. const styles = StyleSheet.create({
  218. aboutView: {
  219. flex: 1,
  220. justifyContent: 'center',
  221. alignItems: 'center',
  222. },
  223. blankView: {
  224. height: 50,
  225. },
  226. aboutViewText: {
  227. color: '#000000',
  228. fontSize: 20,
  229. fontWeight: 'bold',
  230. },
  231. aboutViewDistance: {
  232. marginTop: 10,
  233. },
  234. aboutVersionText: {
  235. color: '#818181',
  236. },
  237. checkUpdateText: {
  238. color: '#6896D4',
  239. fontSize: 14,
  240. },
  241. checkUpdateView: {
  242. alignItems: 'center',
  243. },
  244. speedView1: {
  245. paddingVertical: 20,
  246. },
  247. speedView2: {
  248. flexDirection: 'row',
  249. justifyContent: 'space-between',
  250. alignItems: 'center',
  251. },
  252. speedView3: {
  253. marginRight: 10,
  254. height: 4,
  255. flex: 1,
  256. },
  257. });