From 4261224c4b72b4706da8557f53d8865a8af28010 Mon Sep 17 00:00:00 2001 From: yssk22 Date: Fri, 3 Jan 2025 14:16:29 +0000 Subject: [PATCH] [expo] fix OTA update on Android **Summary** TouchableOpacity was not working on Android due to the invalid style prop. This PR fixes the issue by removing View element and apply the container style to TouchableOpacity. **Test** - expo **Issue** - #155 --- expo/app.config.default.js | 3 +- .../app/__snapshots__/index.test.tsx.snap | 56 ++++++------- .../app/internals/AppUpdateBanner.tsx | 79 ++++++++++--------- 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/expo/app.config.default.js b/expo/app.config.default.js index d687b9a3..892f9053 100644 --- a/expo/app.config.default.js +++ b/expo/app.config.default.js @@ -115,7 +115,8 @@ module.exports = { ] ], updates: { - url: 'https://u.expo.dev/{eas-project-id}' + url: 'https://u.expo.dev/{eas-project-id}', + checkAutomatically: 'NEVER' }, runtimeVersion: { policy: 'appVersion' diff --git a/expo/features/app/__snapshots__/index.test.tsx.snap b/expo/features/app/__snapshots__/index.test.tsx.snap index 31bbf388..fe12de03 100644 --- a/expo/features/app/__snapshots__/index.test.tsx.snap +++ b/expo/features/app/__snapshots__/index.test.tsx.snap @@ -123,7 +123,7 @@ exports[`app AppUpdateBanner show banner 1`] = ` { "busy": undefined, "checked": undefined, - "disabled": false, + "disabled": undefined, "expanded": undefined, "selected": undefined, } @@ -148,54 +148,44 @@ exports[`app AppUpdateBanner show banner 1`] = ` onStartShouldSetResponder={[Function]} style={ { + "alignItems": "center", + "backgroundColor": "#faad14", + "flexDirection": "column", + "justifyContent": "center", "opacity": 1, + "padding": 12, + "paddingBottom": 8, + "paddingTop": 8, + "position": "absolute", + "top": 0, + "width": "100%", } } testID="AppUpdateBanner" > - - - アップデートが利用可能です。タップしてインストール。 - - + ], + ] + } + > + アップデートが利用可能です。タップしてインストール。 + , ] `; diff --git a/expo/features/app/internals/AppUpdateBanner.tsx b/expo/features/app/internals/AppUpdateBanner.tsx index 5b0bec91..c4aecf6e 100644 --- a/expo/features/app/internals/AppUpdateBanner.tsx +++ b/expo/features/app/internals/AppUpdateBanner.tsx @@ -4,15 +4,16 @@ import { FontSize, Spacing } from '@hpapp/features/common/constants'; import { t } from '@hpapp/system/i18n'; import Constants from 'expo-constants'; import * as Updates from 'expo-updates'; -import { useState, useEffect } from 'react'; -import { Alert, AppState, AppStateStatus, TouchableOpacity, StyleSheet, View, Dimensions } from 'react-native'; +import { useState, useEffect, useCallback } from 'react'; +import { AppState, AppStateStatus, TouchableOpacity, StyleSheet } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import * as logging from 'system/logging'; const UPDATE_INTERVAL_MS = 60 * 1000; type BannerAppUpdateState = { - updateAvailable: boolean; + bannerText: string | null; + debugText: string | null; isUpdating: boolean; lastUpdateTimestamp: Date | null; }; @@ -21,7 +22,8 @@ export default function AppUpdateBanner() { const insets = useSafeAreaInsets(); const [color, contrast] = useThemeColor('warning'); const [state, setState] = useState({ - updateAvailable: false, + bannerText: null, + debugText: null, isUpdating: false, lastUpdateTimestamp: null }); @@ -43,20 +45,22 @@ export default function AppUpdateBanner() { if (!unmounted) { setState({ ...state, - updateAvailable: update.isAvailable, + debugText: JSON.stringify(update), + bannerText: update.isAvailable ? t('Update is available - Tap to install.') : null, lastUpdateTimestamp: new Date() }); } } catch (e: any) { if (Constants.expoConfig?.extra?.hpapp?.isDev !== true) { - logging.Error('features.app.AppUpdateBanner', 'failed to check update', { + logging.Error('features.app.AppUpdateBanner', 'failed to aa check update', { error: e.toString() }); } if (!unmounted) { setState({ ...state, - updateAvailable: false, + bannerText: `failed to check update`, + debugText: e.toString(), lastUpdateTimestamp: new Date() }); } @@ -73,48 +77,51 @@ export default function AppUpdateBanner() { unmounted = true; }; }); - - if (!state.updateAvailable) { + const updateApp = useCallback(async () => { + setState({ + ...state, + bannerText: `${t('Updating')}...`, + isUpdating: true + }); + try { + const result = await Updates.fetchUpdateAsync(); + await Updates.reloadAsync(); + setState({ + ...state, + bannerText: null, + debugText: JSON.stringify(result), + isUpdating: false + }); + } catch (e: any) { + setState({ + ...state, + bannerText: `Failed to update: ${e.toString()}`, + debugText: e.toString(), + isUpdating: false + }); + } + }, []); + if (state.bannerText === null) { return null; } - - const text = state.isUpdating ? `${t('Updating')}...` : t('Update is available - Tap to install.'); return ( { - setState({ - ...state, - isUpdating: true - }); - try { - Alert.alert('fetchUpdateAsync'); - await Updates.fetchUpdateAsync(); - Alert.alert('reloadAsync'); - await Updates.reloadAsync(); - } catch (e) { - Alert.alert(e?.toString() ?? 'Unknown error occurrs'); - setState({ - ...state, - isUpdating: false - }); - } - }} + style={[ + styles.container, + { backgroundColor: color, paddingTop: insets.top + Spacing.XSmall, paddingBottom: Spacing.XSmall } + ]} + onPress={updateApp} > - - {text} - + {state.bannerText} ); } -const height = Dimensions.get('window').height; - const styles = StyleSheet.create({ container: { position: 'absolute', - top: -1 * height, + top: 0, width: '100%', flexDirection: 'column', justifyContent: 'center',