From 1cf3733ee212c40ecc7ea6c41c4c2e45e794f023 Mon Sep 17 00:00:00 2001 From: zimplexing Date: Thu, 14 Aug 2025 11:08:54 +0800 Subject: [PATCH] refactor(config): clean up and standardize code formatting in configuration files --- .github/workflows/build-apk.yml | 91 +++------------------------ components/settings/UpdateSection.tsx | 2 +- constants/UpdateConfig.ts | 33 +++++----- hooks/useResponsiveLayout.ts | 68 ++++++++++---------- metro.config.js | 26 ++++---- package.json | 20 ++---- utils/DeviceUtils.ts | 44 ++++++------- 7 files changed, 102 insertions(+), 182 deletions(-) diff --git a/.github/workflows/build-apk.yml b/.github/workflows/build-apk.yml index efb3324..70b709d 100644 --- a/.github/workflows/build-apk.yml +++ b/.github/workflows/build-apk.yml @@ -7,7 +7,7 @@ permissions: contents: write jobs: - build_tv: + direct_build: name: Build Android TV APK runs-on: ubuntu-latest steps: @@ -34,97 +34,24 @@ jobs: java-version: "17" - name: Prebuild TV App - run: yarn prebuild + run: yarn prebuild-tv - name: Build TV APK - run: yarn build-tv + run: yarn build-local - - name: Upload TV APK - uses: actions/upload-artifact@v4 - with: - name: orion-tv-apk - path: android/app/build/outputs/apk/release/app-release.apk - - build_mobile: - name: Build Android Mobile APK - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: "yarn" - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Get version from package.json - id: package-version - run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT - - - name: Setup JDK - uses: actions/setup-java@v3 - with: - distribution: "zulu" - java-version: "17" - - - name: Prebuild Mobile App - run: yarn prebuild - - - name: Build Mobile APK - run: yarn build-mobile - - - name: Upload Mobile APK - uses: actions/upload-artifact@v4 - with: - name: orion-mobile-apk - path: android/app/build/outputs/apk/release/app-release.apk - - release: - name: Create Release - needs: [build_tv, build_mobile] - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@v3 - - - name: Get version from package.json - id: package-version - run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT - - - name: Download TV APK - uses: actions/download-artifact@v4 - with: - name: orion-tv-apk - path: artifacts/tv - - - name: Download Mobile APK - uses: actions/download-artifact@v4 - with: - name: orion-mobile-apk - path: artifacts/mobile - - - name: Rename APK files + - name: Rename APK file run: | - mv artifacts/tv/app-release.apk artifacts/orionTV-tv.${{ steps.package-version.outputs.version }}.apk - mv artifacts/mobile/app-release.apk artifacts/orionTV-mobile.${{ steps.package-version.outputs.version }}.apk + mkdir -p artifacts + cp android/app/build/outputs/apk/release/app-release.apk artifacts/orionTV.${{ steps.package-version.outputs.version }}.apk - - name: Create Release and Upload APKs + - name: Create Release and Upload APK uses: softprops/action-gh-release@v2 with: tag_name: v${{ steps.package-version.outputs.version }} name: Release v${{ steps.package-version.outputs.version }} - body: | - Automated release for version v${{ steps.package-version.outputs.version }}. - - orionTV-tv.${{ steps.package-version.outputs.version }}.apk - Android TV版本 - - orionTV-mobile.${{ steps.package-version.outputs.version }}.apk - 手机/平板版本 + body: Automated release for version v${{ steps.package-version.outputs.version }}. draft: false prerelease: false - files: | - artifacts/orionTV-tv.${{ steps.package-version.outputs.version }}.apk - artifacts/orionTV-mobile.${{ steps.package-version.outputs.version }}.apk + files: artifacts/orionTV.${{ steps.package-version.outputs.version }}.apk env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/components/settings/UpdateSection.tsx b/components/settings/UpdateSection.tsx index 8f6620c..ddf6f9a 100644 --- a/components/settings/UpdateSection.tsx +++ b/components/settings/UpdateSection.tsx @@ -3,7 +3,7 @@ import { View, StyleSheet, Platform, ActivityIndicator } from "react-native"; import { ThemedText } from "../ThemedText"; import { StyledButton } from "../StyledButton"; import { useUpdateStore } from "@/stores/updateStore"; -import { UPDATE_CONFIG } from "@/constants/UpdateConfig"; +// import { UPDATE_CONFIG } from "@/constants/UpdateConfig"; export function UpdateSection() { const { currentVersion, remoteVersion, updateAvailable, downloading, downloadProgress, checkForUpdate } = diff --git a/constants/UpdateConfig.ts b/constants/UpdateConfig.ts index ded2062..72f15b7 100644 --- a/constants/UpdateConfig.ts +++ b/constants/UpdateConfig.ts @@ -1,39 +1,36 @@ -import { DeviceUtils } from '@/utils/DeviceUtils'; - export const UPDATE_CONFIG = { // 自动检查更新 AUTO_CHECK: true, - + // 检查更新间隔(毫秒) CHECK_INTERVAL: 12 * 60 * 60 * 1000, // 12小时 - + // GitHub相关URL - GITHUB_RAW_URL: 'https://ghfast.top/https://raw.githubusercontent.com/zimplexing/OrionTV/refs/heads/master/package.json', - + GITHUB_RAW_URL: + "https://ghfast.top/https://raw.githubusercontent.com/zimplexing/OrionTV/refs/heads/master/package.json", + // 获取平台特定的下载URL getDownloadUrl(version: string): string { - const isTV = DeviceUtils.isTV(); - const platform = isTV ? 'tv' : 'mobile'; - return `https://ghfast.top/https://github.com/zimplexing/OrionTV/releases/download/v${version}/orionTV-${platform}.${version}.apk`; + return `https://ghfast.top/https://github.com/zimplexing/OrionTV/releases/download/v${version}/orionTV.${version}.apk`; }, - + // 是否显示更新日志 SHOW_RELEASE_NOTES: true, - + // 是否允许跳过版本 ALLOW_SKIP_VERSION: true, - + // 下载超时时间(毫秒) DOWNLOAD_TIMEOUT: 10 * 60 * 1000, // 10分钟 - + // 是否在WIFI下自动下载 AUTO_DOWNLOAD_ON_WIFI: false, - + // 更新通知设置 NOTIFICATION: { ENABLED: true, - TITLE: 'OrionTV 更新', - DOWNLOADING_TEXT: '正在下载新版本...', - DOWNLOAD_COMPLETE_TEXT: '下载完成,点击安装', + TITLE: "OrionTV 更新", + DOWNLOADING_TEXT: "正在下载新版本...", + DOWNLOAD_COMPLETE_TEXT: "下载完成,点击安装", }, -}; \ No newline at end of file +}; diff --git a/hooks/useResponsiveLayout.ts b/hooks/useResponsiveLayout.ts index bd95d93..0e32da8 100644 --- a/hooks/useResponsiveLayout.ts +++ b/hooks/useResponsiveLayout.ts @@ -1,7 +1,7 @@ -import { useState, useEffect } from 'react'; -import { Dimensions, Platform } from 'react-native'; +import { useState, useEffect } from "react"; +import { Dimensions, Platform } from "react-native"; -export type DeviceType = 'mobile' | 'tablet' | 'tv'; +export type DeviceType = "mobile" | "tablet" | "tv"; export interface ResponsiveConfig { deviceType: DeviceType; @@ -17,40 +17,44 @@ export interface ResponsiveConfig { const BREAKPOINTS = { mobile: { min: 0, max: 767 }, tablet: { min: 768, max: 1023 }, - tv: { min: 1024, max: Infinity } + tv: { min: 1024, max: Infinity }, }; const getDeviceType = (width: number): DeviceType => { - const isTV = process.env.EXPO_TV === '1' || Platform.isTV; - if (isTV) return 'tv'; - - if (width >= BREAKPOINTS.tv.min) return 'tv'; - if (width >= BREAKPOINTS.tablet.min) return 'tablet'; - return 'mobile'; + if (Platform.isTV) return "tv"; + + if (width >= BREAKPOINTS.tv.min) return "tv"; + if (width >= BREAKPOINTS.tablet.min) return "tablet"; + return "mobile"; }; -const getLayoutConfig = (deviceType: DeviceType, width: number, height: number, isPortrait: boolean): ResponsiveConfig => { - const spacing = deviceType === 'mobile' ? 8 : deviceType === 'tablet' ? 12 : 16; - +const getLayoutConfig = ( + deviceType: DeviceType, + width: number, + height: number, + isPortrait: boolean +): ResponsiveConfig => { + const spacing = deviceType === "mobile" ? 8 : deviceType === "tablet" ? 12 : 16; + let columns: number; let cardWidth: number; let cardHeight: number; switch (deviceType) { - case 'mobile': + case "mobile": columns = isPortrait ? 3 : 4; // 使用flex布局,卡片可以更大一些来填充空间 - cardWidth = (width - spacing) / columns * 0.85; // 增大到85% + cardWidth = ((width - spacing) / columns) * 0.85; // 增大到85% cardHeight = cardWidth * 1.2; // 5:6 aspect ratio (reduced from 2:3) break; - - case 'tablet': + + case "tablet": columns = isPortrait ? 3 : 4; - cardWidth = (width - spacing) / columns * 0.85; // 增大到85% + cardWidth = ((width - spacing) / columns) * 0.85; // 增大到85% cardHeight = cardWidth * 1.4; // slightly less tall ratio break; - - case 'tv': + + case "tv": default: columns = 5; cardWidth = 160; // Fixed width for TV @@ -72,12 +76,12 @@ const getLayoutConfig = (deviceType: DeviceType, width: number, height: number, export const useResponsiveLayout = (): ResponsiveConfig => { const [dimensions, setDimensions] = useState(() => { - const { width, height } = Dimensions.get('window'); + const { width, height } = Dimensions.get("window"); return { width, height }; }); useEffect(() => { - const subscription = Dimensions.addEventListener('change', ({ window }) => { + const subscription = Dimensions.addEventListener("change", ({ window }) => { setDimensions({ width: window.width, height: window.height }); }); @@ -87,7 +91,7 @@ export const useResponsiveLayout = (): ResponsiveConfig => { const { width, height } = dimensions; const isPortrait = height > width; const deviceType = getDeviceType(width); - + return getLayoutConfig(deviceType, width, height, isPortrait); }; @@ -100,31 +104,31 @@ export const useResponsiveValue = (values: { mobile: T; tablet: T; tv: T }): // Utility hook for responsive styles export const useResponsiveStyles = () => { const config = useResponsiveLayout(); - + return { // Common responsive styles container: { paddingHorizontal: config.spacing, }, - + // Card styles cardContainer: { width: config.cardWidth, height: config.cardHeight, marginBottom: config.spacing, }, - + // Grid styles gridContainer: { paddingHorizontal: config.spacing / 2, }, - + // Typography - titleFontSize: config.deviceType === 'mobile' ? 18 : config.deviceType === 'tablet' ? 22 : 28, - bodyFontSize: config.deviceType === 'mobile' ? 14 : config.deviceType === 'tablet' ? 16 : 18, - + titleFontSize: config.deviceType === "mobile" ? 18 : config.deviceType === "tablet" ? 22 : 28, + bodyFontSize: config.deviceType === "mobile" ? 14 : config.deviceType === "tablet" ? 16 : 18, + // Spacing - sectionSpacing: config.deviceType === 'mobile' ? 16 : config.deviceType === 'tablet' ? 20 : 24, + sectionSpacing: config.deviceType === "mobile" ? 16 : config.deviceType === "tablet" ? 20 : 24, itemSpacing: config.spacing, }; -}; \ No newline at end of file +}; diff --git a/metro.config.js b/metro.config.js index 979823c..c97ebc2 100644 --- a/metro.config.js +++ b/metro.config.js @@ -1,6 +1,6 @@ // Learn more https://docs.expo.io/guides/customizing-metro -const {getDefaultConfig} = require('expo/metro-config'); -const path = require('path'); +const { getDefaultConfig } = require("expo/metro-config"); +const path = require("path"); // Find the project and workspace directories // eslint-disable-next-line no-undef @@ -16,24 +16,24 @@ const config = getDefaultConfig(projectRoot); // Metro will still resolve source files with standard extensions // as usual if TV-specific files are not found for a module. // -if (process.env?.EXPO_TV === '1') { - const originalSourceExts = config.resolver.sourceExts; - const tvSourceExts = [ - ...originalSourceExts.map((e) => `tv.${e}`), - ...originalSourceExts, - ]; - config.resolver.sourceExts = tvSourceExts; -} +// if (process.env?.EXPO_TV === '1') { +// const originalSourceExts = config.resolver.sourceExts; +// const tvSourceExts = [ +// ...originalSourceExts.map((e) => `tv.${e}`), +// ...originalSourceExts, +// ]; +// config.resolver.sourceExts = tvSourceExts; +// } // This can be replaced with `find-yarn-workspace-root` -const monorepoRoot = path.resolve(projectRoot, '../..'); +const monorepoRoot = path.resolve(projectRoot, "../.."); // 1. Watch all files within the monorepo config.watchFolders = [monorepoRoot]; // 2. Let Metro know where to resolve packages and in what order config.resolver.nodeModulesPaths = [ - path.resolve(projectRoot, 'node_modules'), - path.resolve(monorepoRoot, 'node_modules'), + path.resolve(projectRoot, "node_modules"), + path.resolve(monorepoRoot, "node_modules"), ]; config.resolver.disableHierarchicalLookup = true; diff --git a/package.json b/package.json index 620b37a..4a16861 100644 --- a/package.json +++ b/package.json @@ -4,20 +4,12 @@ "main": "expo-router/entry", "version": "1.3.0", "scripts": { - "start": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo start", - "start-tv": "EXPO_TV=1 EXPO_USE_METRO_WORKSPACE_ROOT=1 expo start", - "start-mobile": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo start --tunnel", - "android": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:android", - "android-tv": "EXPO_TV=1 EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:android", - "android-mobile": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:android --device", - "ios": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:ios", - "ios-tv": "EXPO_TV=1 EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:ios", - "ios-mobile": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:ios --device", - "prebuild": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo prebuild --clean && yarn copy-config", + "start": "EXPO_TV=1 EXPO_USE_METRO_WORKSPACE_ROOT=1 expo start", + "android": "EXPO_TV=1 EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:android", + "ios": "EXPO_TV=1 EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:ios", + "prebuild": "EXPO_TV=1 EXPO_USE_METRO_WORKSPACE_ROOT=1 expo prebuild --clean && yarn copy-config", "copy-config": "cp -r xml/* android/app/src/*", - "build": "cd android && ./gradlew assembleRelease", - "build-tv": "EXPO_TV=1 yarn prebuild && cd android && ./gradlew assembleRelease", - "build-mobile": "yarn prebuild && cd android && ./gradlew assembleRelease", + "build": "EXPO_TV=1 yarn prebuild && cd android && ./gradlew assembleRelease", "build-debug": "cd android && ./gradlew assembleDebug", "test": "jest --watchAll", "test-ci": "jest --ci --coverage --no-cache", @@ -90,4 +82,4 @@ } }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" -} +} \ No newline at end of file diff --git a/utils/DeviceUtils.ts b/utils/DeviceUtils.ts index e9b208e..a66adbf 100644 --- a/utils/DeviceUtils.ts +++ b/utils/DeviceUtils.ts @@ -1,39 +1,39 @@ -import { Platform, Dimensions } from 'react-native'; -import { DeviceType } from '@/hooks/useResponsiveLayout'; +import { Platform, Dimensions } from "react-native"; +import { DeviceType } from "@/hooks/useResponsiveLayout"; export const DeviceUtils = { /** * 检测当前设备类型 */ getDeviceType(): DeviceType { - const isTV = process.env.EXPO_TV === '1' || Platform.isTV; - if (isTV) return 'tv'; - - const { width } = Dimensions.get('window'); - if (width >= 1024) return 'tv'; - if (width >= 768) return 'tablet'; - return 'mobile'; + // if (Platform.isTV) return "tv"; + + const { width } = Dimensions.get("window"); + + if (width >= 1024) return "tv"; + if (width >= 768) return "tablet"; + return "mobile"; }, /** * 检测是否为TV环境 */ isTV(): boolean { - return this.getDeviceType() === 'tv'; + return this.getDeviceType() === "tv"; }, /** * 检测是否为移动设备 */ isMobile(): boolean { - return this.getDeviceType() === 'mobile'; + return this.getDeviceType() === "mobile"; }, /** * 检测是否为平板设备 */ isTablet(): boolean { - return this.getDeviceType() === 'tablet'; + return this.getDeviceType() === "tablet"; }, /** @@ -56,11 +56,11 @@ export const DeviceUtils = { getMinTouchTargetSize(): number { const deviceType = this.getDeviceType(); switch (deviceType) { - case 'mobile': + case "mobile": return 44; // iOS HIG minimum - case 'tablet': + case "tablet": return 48; // Material Design minimum - case 'tv': + case "tv": return 60; // TV optimized default: return 44; @@ -77,7 +77,7 @@ export const DeviceUtils = { tablet: 1.1, tv: 1.25, }[deviceType]; - + return Math.round(baseSize * scaleFactor); }, @@ -91,7 +91,7 @@ export const DeviceUtils = { tablet: 1.0, tv: 1.5, }[deviceType]; - + return Math.round(baseSpacing * scaleFactor); }, @@ -99,7 +99,7 @@ export const DeviceUtils = { * 检测设备是否处于横屏模式 */ isLandscape(): boolean { - const { width, height } = Dimensions.get('window'); + const { width, height } = Dimensions.get("window"); return width > height; }, @@ -114,10 +114,10 @@ export const DeviceUtils = { * 获取安全的网格列数 */ getSafeColumnCount(preferredColumns: number): number { - const { width } = Dimensions.get('window'); + const { width } = Dimensions.get("window"); const minCardWidth = this.isMobile() ? 120 : this.isTablet() ? 140 : 160; const maxColumns = Math.floor(width / minCardWidth); - + return Math.min(preferredColumns, maxColumns); }, @@ -132,7 +132,7 @@ export const DeviceUtils = { tablet: 1.0, tv: 1.2, }[deviceType]; - + return Math.round(baseDuration * scaleFactor); }, -}; \ No newline at end of file +};