fix(update): resolve APK download path issue and enhance update components

- Fix UpdateService to use DocumentDir instead of DownloadDir for APK storage
- Add retry mechanism for network failures in version checking and downloading
- Implement automatic cleanup of old APK files to manage storage
- Replace TouchableOpacity with StyledButton in UpdateModal for consistency
- Add TV focus control to UpdateSection component
- Reduce category button spacing on TV for better navigation
- Update download URL template to match release naming convention
This commit is contained in:
zimplexing
2025-08-13 17:19:48 +08:00
parent 9e9e4597cc
commit f0c797434d
7 changed files with 241 additions and 228 deletions

View File

@@ -126,7 +126,7 @@ export default function HomeScreen() {
// TV端和平板端的顶部导航
const renderHeader = () => {
if (deviceType === 'mobile') {
if (deviceType === "mobile") {
// 移动端不显示顶部导航使用底部Tab导航
return null;
}
@@ -169,7 +169,7 @@ export default function HomeScreen() {
const dynamicStyles = StyleSheet.create({
container: {
flex: 1,
paddingTop: deviceType === 'mobile' ? 0 : 40,
paddingTop: deviceType === "mobile" ? 0 : 40,
},
headerContainer: {
flexDirection: "row",
@@ -179,7 +179,7 @@ export default function HomeScreen() {
marginBottom: spacing,
},
headerTitle: {
fontSize: deviceType === 'mobile' ? 24 : deviceType === 'tablet' ? 28 : 32,
fontSize: deviceType === "mobile" ? 24 : deviceType === "tablet" ? 28 : 32,
fontWeight: "bold",
paddingTop: 16,
},
@@ -198,13 +198,13 @@ export default function HomeScreen() {
paddingHorizontal: spacing,
},
categoryButton: {
paddingHorizontal: spacing / 2,
paddingHorizontal: deviceType === "tv" ? spacing / 4 : spacing / 2,
paddingVertical: spacing / 2,
borderRadius: deviceType === 'mobile' ? 6 : 8,
marginHorizontal: spacing / 2,
borderRadius: deviceType === "mobile" ? 6 : 8,
marginHorizontal: deviceType === "tv" ? spacing / 4 : spacing / 2, // TV端使用更小的间距
},
categoryText: {
fontSize: deviceType === 'mobile' ? 14 : 16,
fontSize: deviceType === "mobile" ? 14 : 16,
fontWeight: "500",
},
contentContainer: {
@@ -286,13 +286,9 @@ export default function HomeScreen() {
);
// 根据设备类型决定是否包装在响应式导航中
if (deviceType === 'tv') {
if (deviceType === "tv") {
return content;
}
return (
<ResponsiveNavigation>
{content}
</ResponsiveNavigation>
);
}
return <ResponsiveNavigation>{content}</ResponsiveNavigation>;
}

View File

@@ -133,10 +133,8 @@ export default function SettingsScreen() {
// ),
// key: "videoSource",
// },
Platform.OS === 'android' && {
component: (
<UpdateSection />
),
Platform.OS === "android" && {
component: <UpdateSection />,
key: "update",
},
].filter(Boolean);
@@ -144,8 +142,8 @@ export default function SettingsScreen() {
// TV遥控器事件处理 - 仅在TV设备上启用
const handleTVEvent = React.useCallback(
(event: any) => {
if (deviceType !== 'tv') return;
if (deviceType !== "tv") return;
if (event.eventType === "down") {
const nextIndex = Math.min(currentFocusIndex + 1, sections.length);
setCurrentFocusIndex(nextIndex);
@@ -160,18 +158,15 @@ export default function SettingsScreen() {
[currentFocusIndex, sections.length, deviceType]
);
useTVEventHandler(deviceType === 'tv' ? handleTVEvent : () => {});
useTVEventHandler(deviceType === "tv" ? handleTVEvent : () => {});
// 动态样式
const dynamicStyles = createResponsiveStyles(deviceType, spacing);
const renderSettingsContent = () => (
<KeyboardAvoidingView
style={{ flex: 1, backgroundColor }}
behavior={Platform.OS === "ios" ? "padding" : "height"}
>
<KeyboardAvoidingView style={{ flex: 1, backgroundColor }} behavior={Platform.OS === "ios" ? "padding" : "height"}>
<ThemedView style={[commonStyles.container, dynamicStyles.container]}>
{deviceType === 'tv' && (
{deviceType === "tv" && (
<View style={dynamicStyles.header}>
<ThemedText style={dynamicStyles.title}></ThemedText>
</View>
@@ -186,7 +181,7 @@ export default function SettingsScreen() {
}
return null;
}}
keyExtractor={(item) => item ? item.key : 'default'}
keyExtractor={(item) => (item ? item.key : "default")}
showsVerticalScrollIndicator={false}
contentContainerStyle={dynamicStyles.listContent}
/>
@@ -198,10 +193,7 @@ export default function SettingsScreen() {
onPress={handleSave}
variant="primary"
disabled={!hasChanges || isLoading}
style={[
dynamicStyles.saveButton,
(!hasChanges || isLoading) && dynamicStyles.disabledButton
]}
style={[dynamicStyles.saveButton, (!hasChanges || isLoading) && dynamicStyles.disabledButton]}
/>
</View>
</ThemedView>
@@ -209,7 +201,7 @@ export default function SettingsScreen() {
);
// 根据设备类型决定是否包装在响应式导航中
if (deviceType === 'tv') {
if (deviceType === "tv") {
return renderSettingsContent();
}
@@ -222,9 +214,9 @@ export default function SettingsScreen() {
}
const createResponsiveStyles = (deviceType: string, spacing: number) => {
const isMobile = deviceType === 'mobile';
const isTablet = deviceType === 'tablet';
const isTV = deviceType === 'tv';
const isMobile = deviceType === "mobile";
const isTablet = deviceType === "tablet";
const isTV = deviceType === "tv";
const minTouchTarget = DeviceUtils.getMinTouchTargetSize();
return StyleSheet.create({
@@ -243,7 +235,7 @@ const createResponsiveStyles = (deviceType: string, spacing: number) => {
fontSize: isMobile ? 24 : isTablet ? 28 : 32,
fontWeight: "bold",
paddingTop: spacing,
color: 'white',
color: "white",
},
scrollView: {
flex: 1,
@@ -257,7 +249,7 @@ const createResponsiveStyles = (deviceType: string, spacing: number) => {
},
saveButton: {
minHeight: isMobile ? minTouchTarget : isTablet ? 50 : 50,
width: isMobile ? '100%' : isTablet ? 140 : 120,
width: isMobile ? "100%" : isTablet ? 140 : 120,
maxWidth: isMobile ? 280 : undefined,
},
disabledButton: {