fix: 修复 Android 闪退问题 - SecureStore 异步调用
问题: - NativeStorage 使用了同步方法调用 expo-secure-store - expo-secure-store 的正确 API 是异步的(getItemAsync/setItemAsync/deleteItemAsync) - 在 Android 上同步调用不存在的方法导致应用崩溃 修复: - 将 Storage 接口改为异步方法 - 使用 SecureStore.getItemAsync/setItemAsync/deleteItemAsync - removeItem 使用 deleteItemAsync 而不是设置空字符串 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -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 (
|
||||
<VideoView
|
||||
player={player}
|
||||
style={style}
|
||||
contentFit="contain"
|
||||
allowsFullscreen
|
||||
allowsPictureInPicture
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
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
|
||||
/>
|
||||
) : (
|
||||
<View style={{ width: '100%', height: VIDEO_HEIGHT }}>
|
||||
<ThemedText>Video: {url}</ThemedText>
|
||||
</View>
|
||||
<NativeVideoPlayer
|
||||
url={url}
|
||||
style={{ width: '100%', height: VIDEO_HEIGHT }}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<Image
|
||||
@@ -435,9 +445,10 @@ export default function ResultPage() {
|
||||
controls
|
||||
/>
|
||||
) : (
|
||||
<View style={styles.fullscreenMediaContent}>
|
||||
<ThemedText>Video Player</ThemedText>
|
||||
</View>
|
||||
<NativeVideoPlayer
|
||||
url={fullscreenContent.url}
|
||||
style={styles.fullscreenMediaContent}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user