Skip to content

Commit

Permalink
[expo] fix OTA update on Android
Browse files Browse the repository at this point in the history
**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
  • Loading branch information
yssk22 committed Jan 3, 2025
1 parent a80eaa7 commit 4261224
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 70 deletions.
3 changes: 2 additions & 1 deletion expo/app.config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
56 changes: 23 additions & 33 deletions expo/features/app/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ exports[`app AppUpdateBanner show banner 1`] = `
{
"busy": undefined,
"checked": undefined,
"disabled": false,
"disabled": undefined,
"expanded": undefined,
"selected": undefined,
}
Expand All @@ -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"
>
<View
<Text
style={
[
{
"alignItems": "center",
"flexDirection": "column",
"justifyContent": "center",
"padding": 12,
"position": "absolute",
"top": -1334,
"width": "100%",
"color": "black",
},
{
"backgroundColor": "#faad14",
"paddingTop": 0,
"fontSize": 14,
},
]
}
>
<Text
style={
[
{
"color": "black",
"fontSize": 14,
"textAlign": "center",
},
{
"fontSize": 14,
"color": "#ffffff",
},
[
{
"fontSize": 14,
"textAlign": "center",
},
{
"color": "#ffffff",
},
],
]
}
>
アップデートが利用可能です。タップしてインストール。
</Text>
</View>
],
]
}
>
アップデートが利用可能です。タップしてインストール。
</Text>
</View>,
]
`;
79 changes: 43 additions & 36 deletions expo/features/app/internals/AppUpdateBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand All @@ -21,7 +22,8 @@ export default function AppUpdateBanner() {
const insets = useSafeAreaInsets();
const [color, contrast] = useThemeColor('warning');
const [state, setState] = useState<BannerAppUpdateState>({
updateAvailable: false,
bannerText: null,
debugText: null,
isUpdating: false,
lastUpdateTimestamp: null
});
Expand All @@ -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()
});
}
Expand All @@ -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 (
<TouchableOpacity
testID="AppUpdateBanner"
disabled={state.isUpdating}
onPress={async () => {
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}
>
<View style={[styles.container, { backgroundColor: color, paddingTop: insets.top }]}>
<Text style={[styles.text, { color: contrast }]}>{text}</Text>
</View>
<Text style={[styles.text, { color: contrast }]}>{state.bannerText}</Text>
</TouchableOpacity>
);
}

const height = Dimensions.get('window').height;

const styles = StyleSheet.create({
container: {
position: 'absolute',
top: -1 * height,
top: 0,
width: '100%',
flexDirection: 'column',
justifyContent: 'center',
Expand Down

0 comments on commit 4261224

Please sign in to comment.