diff --git a/app.json b/app.json index 6accc99..8c0a32a 100644 --- a/app.json +++ b/app.json @@ -20,7 +20,8 @@ }, "edgeToEdgeEnabled": true, "predictiveBackGestureEnabled": false, - "package": "com.anonymous.bwexpoappv3" + "package": "com.anonymous.bwexpoappv3", + "versionCode": 3 }, "web": { "output": "static", @@ -42,7 +43,8 @@ ], "expo-video", "expo-audio", - "expo-web-browser" + "expo-web-browser", + "expo-asset" ], "experiments": { "typedRoutes": true, @@ -53,6 +55,6 @@ "projectId": "191f0396-3e0c-40ec-bd06-b15f58278b8f" } }, - "owner": "imeepos" + "owner": "bowong" } } diff --git a/app/result.tsx b/app/result.tsx index 447321c..2a0f686 100644 --- a/app/result.tsx +++ b/app/result.tsx @@ -1,10 +1,29 @@ import { ThemedView } from '@/components/themed-view'; -import { VideoView, useVideoPlayer } from 'expo-video'; -import * as MediaLibrary from 'expo-media-library'; -import * as FileSystem from 'expo-file-system'; -import { Platform } from 'react-native'; -import { ThemedText } from '@/components/themed-text'; import { getTemplateGeneration } from '@/lib/api/template-runs'; +import * as Clipboard from 'expo-clipboard'; +import * as FileSystem from 'expo-file-system'; +import * as MediaLibrary from 'expo-media-library'; +import { router, useLocalSearchParams } from 'expo-router'; +import { VideoView, useVideoPlayer } from 'expo-video'; +import { + ArrowLeft, + Copy, + Download, + Maximize2, + Plus, + X, +} from 'lucide-react'; +import React, { useEffect, useState } from 'react'; +import { + ActivityIndicator, + Alert, + Dimensions, + Image, Modal, Platform, ScrollView, + StyleSheet, Text, + TouchableOpacity, + View +} from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; // ResizeMode 兼容映射 - 移除 'stretch',expo-video 不支持 const ResizeMode = { @@ -12,43 +31,33 @@ const ResizeMode = { COVER: 'cover' as const, STRETCH: 'fill' as const, // 使用 'fill' 替代 'stretch' }; -import { router, useLocalSearchParams } from 'expo-router'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { - Copy, - Download, - Maximize2, - Plus, - X, - ArrowLeft, -} from 'lucide-react'; -import React, { useEffect, useState } from 'react'; -import { - ActivityIndicator, - Alert, - Dimensions, - Image, - ImageStyle, - Modal, - ScrollView, - StyleSheet, - StyleProp, - Text, - TouchableOpacity, - View, - ViewStyle, - FlatList, -} from 'react-native'; const { width: screenWidth, height: screenHeight } = Dimensions.get('window'); const HERO_HEIGHT = screenWidth * 0.58; const VIDEO_HEIGHT = screenHeight * 0.6; +// 原生视频播放组件 +const NativeVideoPlayer: React.FC<{ url: string; style?: any }> = ({ url, style }) => { + const player = useVideoPlayer(url, player => { + player.loop = false; + }); + + return ( + + ); +}; + interface ResultWithTemplate { id: string; userId: string; templateId: string; - type: 'TEXT' | 'IMAGE' | 'VIDEO'; + type: 'UNKNOWN' | 'TEXT' | 'IMAGE' | 'VIDEO'; resultUrl: string[]; status: 'pending' | 'running' | 'completed' | 'failed'; creditsCost?: number; @@ -233,7 +242,7 @@ export default function ResultPage() { if (!result || result.type !== 'TEXT') return; try { - await navigator.clipboard?.writeText?.(result.resultUrl[0]); + await Clipboard.setStringAsync(result.resultUrl[0]); Alert.alert('复制成功', '文本已复制到剪贴板'); } catch (error) { Alert.alert('复制失败', '无法复制文本'); @@ -306,9 +315,10 @@ export default function ResultPage() { playsInline /> ) : ( - - Video: {url} - + ) ) : ( ) : ( - - Video Player - + )} )} diff --git a/app/templates/[id].tsx b/app/templates/[id].tsx index 5905267..972c818 100644 --- a/app/templates/[id].tsx +++ b/app/templates/[id].tsx @@ -87,6 +87,7 @@ export default function TemplateDetailScreen() { const [menuVisible, setMenuVisible] = useState(false); const [loadingLooks, setLoadingLooks] = useState(true); const [errorMessage, setErrorMessage] = useState(null); + const [retryTrigger, setRetryTrigger] = useState(0); const abortControllerRef = useRef(null); const imageCache = useRef(new Set()); @@ -242,22 +243,15 @@ export default function TemplateDetailScreen() { cache.delete(`tag:${current?.title}`); setErrorMessage(null); setLoadingLooks(true); - - const event = new Event('retry'); - window.dispatchEvent(event); + setRetryTrigger(prev => prev + 1); }, [id, current?.title]); useEffect(() => { - const handleRetryEvent = () => { + if (retryTrigger > 0) { const newController = new AbortController(); abortControllerRef.current = newController; - }; - - window.addEventListener('retry', handleRetryEvent); - return () => { - window.removeEventListener('retry', handleRetryEvent); - }; - }, []); + } + }, [retryTrigger]); const handleGenerate = () => { if (!resolvedTemplateId) { diff --git a/bun.lock b/bun.lock index 196c7c4..57f64c9 100644 --- a/bun.lock +++ b/bun.lock @@ -16,8 +16,11 @@ "better-auth": "1.3.27", "eas-cli": "^16.22.0", "expo": "54.0.23", + "expo-asset": "~12.0.9", "expo-audio": "~1.0.14", + "expo-clipboard": "~8.0.7", "expo-constants": "~18.0.10", + "expo-crypto": "~15.0.7", "expo-dev-client": "~6.0.17", "expo-file-system": "~19.0.17", "expo-font": "~14.0.9", @@ -312,7 +315,7 @@ "@expo/fingerprint": ["@expo/fingerprint@0.15.3", "", { "dependencies": { "@expo/spawn-async": "^1.7.2", "arg": "^5.0.2", "chalk": "^4.1.2", "debug": "^4.3.4", "getenv": "^2.0.0", "glob": "^10.4.2", "ignore": "^5.3.1", "minimatch": "^9.0.0", "p-limit": "^3.1.0", "resolve-from": "^5.0.0", "semver": "^7.6.0" }, "bin": { "fingerprint": "bin/cli.js" } }, "sha512-8YPJpEYlmV171fi+t+cSLMX1nC5ngY9j2FiN70dHldLpd6Ct6ouGhk96svJ4BQZwsqwII2pokwzrDAwqo4Z0FQ=="], - "@expo/image-utils": ["@expo/image-utils@0.6.5", "https://registry.npmmirror.com/@expo/image-utils/-/image-utils-0.6.5.tgz", { "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "fs-extra": "9.0.0", "getenv": "^1.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "resolve-from": "^5.0.0", "semver": "^7.6.0", "temp-dir": "~2.0.0", "unique-string": "~2.0.0" } }, "sha512-RsS/1CwJYzccvlprYktD42KjyfWZECH6PPIEowvoSmXfGLfdViwcUEI4RvBfKX5Jli6P67H+6YmHvPTbGOboew=="], + "@expo/image-utils": ["@expo/image-utils@0.8.7", "https://registry.npmmirror.com/@expo/image-utils/-/image-utils-0.8.7.tgz", { "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "resolve-from": "^5.0.0", "resolve-global": "^1.0.0", "semver": "^7.6.0", "temp-dir": "~2.0.0", "unique-string": "~2.0.0" } }, "sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w=="], "@expo/json-file": ["@expo/json-file@8.3.3", "https://registry.npmmirror.com/@expo/json-file/-/json-file-8.3.3.tgz", { "dependencies": { "@babel/code-frame": "~7.10.4", "json5": "^2.2.2", "write-file-atomic": "^2.3.0" } }, "sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A=="], @@ -1072,6 +1075,8 @@ "expo-audio": ["expo-audio@1.0.14", "", { "peerDependencies": { "expo": "*", "expo-asset": "*", "react": "*", "react-native": "*" } }, "sha512-UU8n1mIDPfO9zFQbPnIpnzhHeqC8c8WQUoOOFvlgI5CeOJMUrQ6UXDpX+LBcHxw/amSBhF5HP6VMr58foPKwbA=="], + "expo-clipboard": ["expo-clipboard@8.0.7", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-zvlfFV+wB2QQrQnHWlo0EKHAkdi2tycLtE+EXFUWTPZYkgu1XcH+aiKfd4ul7Z0SDF+1IuwoiW9AA9eO35aj3Q=="], + "expo-constants": ["expo-constants@18.0.10", "", { "dependencies": { "@expo/config": "~12.0.10", "@expo/env": "~2.0.7" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-Rhtv+X974k0Cahmvx6p7ER5+pNhBC0XbP1lRviL2J1Xl4sT2FBaIuIxF/0I0CbhOsySf0ksqc5caFweAy9Ewiw=="], "expo-crypto": ["expo-crypto@15.0.7", "https://registry.npmmirror.com/expo-crypto/-/expo-crypto-15.0.7.tgz", { "dependencies": { "base64-js": "^1.3.0" }, "peerDependencies": { "expo": "*" } }, "sha512-FUo41TwwGT2e5rA45PsjezI868Ch3M6wbCZsmqTWdF/hr+HyPcrp1L//dsh/hsrsyrQdpY/U96Lu71/wXePJeg=="], @@ -2216,8 +2221,6 @@ "@expo/cli/@expo/env": ["@expo/env@2.0.7", "https://registry.npmmirror.com/@expo/env/-/env-2.0.7.tgz", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "getenv": "^2.0.0" } }, "sha512-BNETbLEohk3HQ2LxwwezpG8pq+h7Fs7/vAMP3eAtFT1BCpprLYoBBFZH7gW4aqGfqOcVP4Lc91j014verrYNGg=="], - "@expo/cli/@expo/image-utils": ["@expo/image-utils@0.8.7", "https://registry.npmmirror.com/@expo/image-utils/-/image-utils-0.8.7.tgz", { "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "resolve-from": "^5.0.0", "resolve-global": "^1.0.0", "semver": "^7.6.0", "temp-dir": "~2.0.0", "unique-string": "~2.0.0" } }, "sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w=="], - "@expo/cli/@expo/json-file": ["@expo/json-file@10.0.7", "https://registry.npmmirror.com/@expo/json-file/-/json-file-10.0.7.tgz", { "dependencies": { "@babel/code-frame": "~7.10.4", "json5": "^2.2.3" } }, "sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw=="], "@expo/cli/@expo/osascript": ["@expo/osascript@2.3.7", "https://registry.npmmirror.com/@expo/osascript/-/osascript-2.3.7.tgz", { "dependencies": { "@expo/spawn-async": "^1.7.2", "exec-async": "^2.2.0" } }, "sha512-IClSOXxR0YUFxIriUJVqyYki7lLMIHrrzOaP01yxAL1G8pj2DWV5eW1y5jSzIcIfSCNhtGsshGd1tU/AYup5iQ=="], @@ -2288,7 +2291,7 @@ "@expo/fingerprint/semver": ["semver@7.7.3", "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "@expo/image-utils/fs-extra": ["fs-extra@9.0.0", "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.0.0.tgz", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^1.0.0" } }, "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g=="], + "@expo/image-utils/getenv": ["getenv@2.0.0", "https://registry.npmmirror.com/getenv/-/getenv-2.0.0.tgz", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="], "@expo/image-utils/semver": ["semver@7.7.3", "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], @@ -2332,6 +2335,8 @@ "@expo/plugin-warn-if-update-available/tslib": ["tslib@2.8.1", "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@expo/prebuild-config/@expo/image-utils": ["@expo/image-utils@0.6.5", "https://registry.npmmirror.com/@expo/image-utils/-/image-utils-0.6.5.tgz", { "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "fs-extra": "9.0.0", "getenv": "^1.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "resolve-from": "^5.0.0", "semver": "^7.6.0", "temp-dir": "~2.0.0", "unique-string": "~2.0.0" } }, "sha512-RsS/1CwJYzccvlprYktD42KjyfWZECH6PPIEowvoSmXfGLfdViwcUEI4RvBfKX5Jli6P67H+6YmHvPTbGOboew=="], + "@expo/prebuild-config/@expo/json-file": ["@expo/json-file@9.1.5", "https://registry.npmmirror.com/@expo/json-file/-/json-file-9.1.5.tgz", { "dependencies": { "@babel/code-frame": "~7.10.4", "json5": "^2.2.3" } }, "sha512-prWBhLUlmcQtvN6Y7BpW2k9zXGd3ySa3R6rAguMJkp1z22nunLN64KYTUWfijFlprFoxm9r2VNnGkcbndAlgKA=="], "@expo/prebuild-config/@react-native/normalize-colors": ["@react-native/normalize-colors@0.76.2", "https://registry.npmmirror.com/@react-native/normalize-colors/-/normalize-colors-0.76.2.tgz", {}, "sha512-ICoOpaTLPsFQjNLSM00NgQr6wal300cZZonHVSDXKntX+BfkLeuCHRtr/Mn+klTtW+/1v2/2FRm9dXjvyGf9Dw=="], @@ -2480,8 +2485,6 @@ "expo/@expo/config-plugins": ["@expo/config-plugins@54.0.2", "https://registry.npmmirror.com/@expo/config-plugins/-/config-plugins-54.0.2.tgz", { "dependencies": { "@expo/config-types": "^54.0.8", "@expo/json-file": "~10.0.7", "@expo/plist": "^0.4.7", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^10.4.2", "resolve-from": "^5.0.0", "semver": "^7.5.4", "slash": "^3.0.0", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-jD4qxFcURQUVsUFGMcbo63a/AnviK8WUGard+yrdQE3ZrB/aurn68SlApjirQQLEizhjI5Ar2ufqflOBlNpyPg=="], - "expo-asset/@expo/image-utils": ["@expo/image-utils@0.8.7", "https://registry.npmmirror.com/@expo/image-utils/-/image-utils-0.8.7.tgz", { "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "resolve-from": "^5.0.0", "resolve-global": "^1.0.0", "semver": "^7.6.0", "temp-dir": "~2.0.0", "unique-string": "~2.0.0" } }, "sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w=="], - "expo-asset/expo-constants": ["expo-constants@18.0.9", "https://registry.npmmirror.com/expo-constants/-/expo-constants-18.0.9.tgz", { "dependencies": { "@expo/config": "~12.0.9", "@expo/env": "~2.0.7" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-sqoXHAOGDcr+M9NlXzj1tGoZyd3zxYDy215W6E0Z0n8fgBaqce9FAYQE2bu5X4G629AYig5go7U6sQz7Pjcm8A=="], "expo-constants/@expo/config": ["@expo/config@12.0.10", "https://registry.npmmirror.com/@expo/config/-/config-12.0.10.tgz", { "dependencies": { "@babel/code-frame": "~7.10.4", "@expo/config-plugins": "~54.0.2", "@expo/config-types": "^54.0.8", "@expo/json-file": "^10.0.7", "deepmerge": "^4.3.1", "getenv": "^2.0.0", "glob": "^10.4.2", "require-from-string": "^2.0.2", "resolve-from": "^5.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4", "sucrase": "3.35.0" } }, "sha512-lJMof5Nqakq1DxGYlghYB/ogSBjmv4Fxn1ovyDmcjlRsQdFCXgu06gEUogkhPtc9wBt9WlTTfqENln5HHyLW6w=="], @@ -2704,8 +2707,6 @@ "@expo/fingerprint/minimatch/brace-expansion": ["brace-expansion@2.0.2", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], - "@expo/image-utils/fs-extra/universalify": ["universalify@1.0.0", "https://registry.npmmirror.com/universalify/-/universalify-1.0.0.tgz", {}, "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="], - "@expo/metro-config/@expo/config/@babel/code-frame": ["@babel/code-frame@7.10.4", "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.10.4.tgz", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="], "@expo/metro-config/@expo/config/@expo/config-plugins": ["@expo/config-plugins@54.0.2", "https://registry.npmmirror.com/@expo/config-plugins/-/config-plugins-54.0.2.tgz", { "dependencies": { "@expo/config-types": "^54.0.8", "@expo/json-file": "~10.0.7", "@expo/plist": "^0.4.7", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^10.4.2", "resolve-from": "^5.0.0", "semver": "^7.5.4", "slash": "^3.0.0", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-jD4qxFcURQUVsUFGMcbo63a/AnviK8WUGard+yrdQE3ZrB/aurn68SlApjirQQLEizhjI5Ar2ufqflOBlNpyPg=="], @@ -2742,6 +2743,8 @@ "@expo/plugin-warn-if-update-available/@oclif/core/supports-color": ["supports-color@8.1.1", "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + "@expo/prebuild-config/@expo/image-utils/fs-extra": ["fs-extra@9.0.0", "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.0.0.tgz", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^1.0.0" } }, "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g=="], + "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], "@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], @@ -2804,10 +2807,6 @@ "eas-cli/minimatch/brace-expansion": ["brace-expansion@2.0.2", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], - "expo-asset/@expo/image-utils/getenv": ["getenv@2.0.0", "https://registry.npmmirror.com/getenv/-/getenv-2.0.0.tgz", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="], - - "expo-asset/@expo/image-utils/semver": ["semver@7.7.3", "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "expo-asset/expo-constants/@expo/config": ["@expo/config@12.0.10", "https://registry.npmmirror.com/@expo/config/-/config-12.0.10.tgz", { "dependencies": { "@babel/code-frame": "~7.10.4", "@expo/config-plugins": "~54.0.2", "@expo/config-types": "^54.0.8", "@expo/json-file": "^10.0.7", "deepmerge": "^4.3.1", "getenv": "^2.0.0", "glob": "^10.4.2", "require-from-string": "^2.0.2", "resolve-from": "^5.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4", "sucrase": "3.35.0" } }, "sha512-lJMof5Nqakq1DxGYlghYB/ogSBjmv4Fxn1ovyDmcjlRsQdFCXgu06gEUogkhPtc9wBt9WlTTfqENln5HHyLW6w=="], "expo-asset/expo-constants/@expo/env": ["@expo/env@2.0.7", "https://registry.npmmirror.com/@expo/env/-/env-2.0.7.tgz", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "getenv": "^2.0.0" } }, "sha512-BNETbLEohk3HQ2LxwwezpG8pq+h7Fs7/vAMP3eAtFT1BCpprLYoBBFZH7gW4aqGfqOcVP4Lc91j014verrYNGg=="], @@ -2850,8 +2849,6 @@ "expo-splash-screen/@expo/prebuild-config/@expo/config-types": ["@expo/config-types@54.0.8", "https://registry.npmmirror.com/@expo/config-types/-/config-types-54.0.8.tgz", {}, "sha512-lyIn/x/Yz0SgHL7IGWtgTLg6TJWC9vL7489++0hzCHZ4iGjVcfZmPTUfiragZ3HycFFj899qN0jlhl49IHa94A=="], - "expo-splash-screen/@expo/prebuild-config/@expo/image-utils": ["@expo/image-utils@0.8.7", "https://registry.npmmirror.com/@expo/image-utils/-/image-utils-0.8.7.tgz", { "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "resolve-from": "^5.0.0", "resolve-global": "^1.0.0", "semver": "^7.6.0", "temp-dir": "~2.0.0", "unique-string": "~2.0.0" } }, "sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w=="], - "expo-splash-screen/@expo/prebuild-config/@expo/json-file": ["@expo/json-file@10.0.7", "https://registry.npmmirror.com/@expo/json-file/-/json-file-10.0.7.tgz", { "dependencies": { "@babel/code-frame": "~7.10.4", "json5": "^2.2.3" } }, "sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw=="], "expo-splash-screen/@expo/prebuild-config/@react-native/normalize-colors": ["@react-native/normalize-colors@0.81.4", "https://registry.npmmirror.com/@react-native/normalize-colors/-/normalize-colors-0.81.4.tgz", {}, "sha512-9nRRHO1H+tcFqjb9gAM105Urtgcanbta2tuqCVY0NATHeFPDEAB7gPyiLxCHKMi1NbhP6TH0kxgSWXKZl1cyRg=="], @@ -2954,6 +2951,8 @@ "@expo/plugin-warn-if-update-available/@oclif/core/js-yaml/argparse": ["argparse@1.0.10", "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + "@expo/prebuild-config/@expo/image-utils/fs-extra/universalify": ["universalify@1.0.0", "https://registry.npmmirror.com/universalify/-/universalify-1.0.0.tgz", {}, "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="], + "@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], "@oclif/plugin-autocomplete/@oclif/core/js-yaml/argparse": ["argparse@1.0.10", "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], @@ -3016,8 +3015,6 @@ "expo-splash-screen/@expo/prebuild-config/@expo/config-plugins/glob": ["glob@10.4.5", "https://registry.npmmirror.com/glob/-/glob-10.4.5.tgz", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], - "expo-splash-screen/@expo/prebuild-config/@expo/image-utils/getenv": ["getenv@2.0.0", "https://registry.npmmirror.com/getenv/-/getenv-2.0.0.tgz", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="], - "expo/@expo/config-plugins/@expo/plist/@xmldom/xmldom": ["@xmldom/xmldom@0.8.11", "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz", {}, "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw=="], "expo/@expo/config-plugins/@expo/plist/xmlbuilder": ["xmlbuilder@15.1.1", "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], diff --git a/components/CommonHeader.tsx b/components/CommonHeader.tsx index 5294a19..d80130c 100644 --- a/components/CommonHeader.tsx +++ b/components/CommonHeader.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; import { ArrowLeft } from 'lucide-react'; +import { router } from 'expo-router'; import { Colors, Spacing, FontSize, Layout } from '@/constants/theme'; interface CommonHeaderProps { @@ -23,9 +24,7 @@ export const CommonHeader: React.FC = ({ onBack(); return; } - if (typeof window !== 'undefined' && window.history) { - window.history.back(); - } + router.back(); }; return ( diff --git a/components/templates/template-card.tsx b/components/templates/template-card.tsx index 1dd9938..5f38ed2 100644 --- a/components/templates/template-card.tsx +++ b/components/templates/template-card.tsx @@ -122,7 +122,7 @@ export function TemplateCard({ )} {template.category && ( - + {template.category.name} @@ -132,7 +132,7 @@ export function TemplateCard({ )} {template.tags.length > 0 && ( - + {template.tags.slice(0, 2).map((tag) => ( diff --git a/components/ui/user-count-badge.tsx b/components/ui/user-count-badge.tsx index a768bc7..e2ca8a5 100644 --- a/components/ui/user-count-badge.tsx +++ b/components/ui/user-count-badge.tsx @@ -41,7 +41,7 @@ export function UserCountBadge({ const displayText = formatCount(count); return ( - + {showIcon && ( ; + setItem(key: string, value: string): Promise; + removeItem(key: string): Promise; } class WebStorage implements Storage { - getItem(key: string): string | null { + async getItem(key: string): Promise { if (typeof window === "undefined") return null; return window.localStorage.getItem(key); } - setItem(key: string, value: string) { + async setItem(key: string, value: string): Promise { if (typeof window === "undefined") return; window.localStorage.setItem(key, value); } - removeItem(key: string) { + async removeItem(key: string): Promise { if (typeof window === "undefined") return; console.log(`[WebStorage] Removing key: ${key}`); window.localStorage.removeItem(key); @@ -27,18 +27,18 @@ class WebStorage implements Storage { } class NativeStorage implements Storage { - getItem(key: string): string | null { - return SecureStore.getItem(key); + async getItem(key: string): Promise { + return await SecureStore.getItemAsync(key); } - setItem(key: string, value: string) { - SecureStore.setItem(key, value); + async setItem(key: string, value: string): Promise { + await SecureStore.setItemAsync(key, value); } - removeItem(key: string) { + async removeItem(key: string): Promise { console.log(`[NativeStorage] Removing key: ${key}`); - SecureStore.setItem(key, ""); - console.log(`[NativeStorage] Key set to empty string`); + await SecureStore.deleteItemAsync(key); + console.log(`[NativeStorage] Key removed`); } } diff --git a/package.json b/package.json index 669153a..2ea9c2f 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,11 @@ "better-auth": "1.3.27", "eas-cli": "^16.22.0", "expo": "54.0.23", + "expo-asset": "~12.0.9", "expo-audio": "~1.0.14", + "expo-clipboard": "~8.0.7", "expo-constants": "~18.0.10", + "expo-crypto": "~15.0.7", "expo-dev-client": "~6.0.17", "expo-file-system": "~19.0.17", "expo-font": "~14.0.9", diff --git a/todo.md b/todo.md new file mode 100644 index 0000000..6de77c8 --- /dev/null +++ b/todo.md @@ -0,0 +1,6 @@ +/plan 检查代码中不符合expo/react-native最佳实践规范的代码,如div/video/img等只有h5中才有的标签没有适配多平台等问题 + +我的目标是三个端正常运行: +1. h5 web 端 +2. android 端 +3. ios 端 \ No newline at end of file