73 lines
2.5 KiB
TypeScript
73 lines
2.5 KiB
TypeScript
import i18n from '@/i18n';
|
|
import { PermissionService } from '@/lib/PermissionService';
|
|
import * as Haptics from 'expo-haptics';
|
|
import * as MediaLibrary from 'expo-media-library';
|
|
import React, { useRef } from 'react';
|
|
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
import QRCode from 'react-native-qrcode-svg';
|
|
import { captureRef } from 'react-native-view-shot';
|
|
|
|
export default function QRDownloadScreen(prop: { url: string }) {
|
|
const qrViewRef = useRef<View>(null); // 用于截图的引用
|
|
const [qrValue] = React.useState(prop.url); // 二维码内容
|
|
|
|
const saveQRToGallery = async () => {
|
|
try {
|
|
// 触发轻震,提升交互感
|
|
await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
|
|
|
// 请求相册写入权限
|
|
const { status } = await MediaLibrary.requestPermissionsAsync();
|
|
if (status !== 'granted') {
|
|
PermissionService.show({ title: i18n.t('permission:title.permissionDenied'), message: i18n.t('permission:message.saveToAlbumPermissionRequired') });
|
|
return;
|
|
}
|
|
|
|
if (!qrViewRef.current) return;
|
|
|
|
// 截取二维码视图
|
|
const uri = await captureRef(qrViewRef, {
|
|
format: 'png',
|
|
quality: 1,
|
|
result: 'tmpfile', // 返回临时文件路径
|
|
});
|
|
|
|
// 保存到相册
|
|
await MediaLibrary.saveToLibraryAsync(uri);
|
|
|
|
PermissionService.show({ title: i18n.t('permission:title.success'), message: i18n.t('permission:message.qrCodeSaved') });
|
|
} catch (error) {
|
|
console.error('保存失败:', error);
|
|
PermissionService.show({ title: i18n.t('permission:title.error'), message: i18n.t('permission:message.saveImageFailed') });
|
|
}
|
|
};
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
{/* 可截图的容器 */}
|
|
<TouchableOpacity onLongPress={saveQRToGallery} activeOpacity={0.8}>
|
|
<View ref={qrViewRef} style={styles.qrContainer}>
|
|
<QRCode value={qrValue} size={200} />
|
|
</View>
|
|
</TouchableOpacity>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
// flex: 1,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
qrContainer: {
|
|
padding: 16,
|
|
backgroundColor: '#fff',
|
|
borderRadius: 12,
|
|
},
|
|
tip: {
|
|
marginTop: 20,
|
|
color: '#666',
|
|
fontSize: 14,
|
|
},
|
|
}); |