feat: 下载页面 #12
@ -316,6 +316,17 @@ export default function TabLayout() {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 下载页面 */}
|
||||
<Tabs.Screen
|
||||
name="download"
|
||||
options={{
|
||||
title: 'download',
|
||||
tabBarButton: () => null, // 隐藏底部标签栏
|
||||
headerShown: false, // 隐藏导航栏
|
||||
tabBarStyle: { display: 'none' } // 确保在标签栏中不显示
|
||||
}}
|
||||
/>
|
||||
</Tabs >
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,63 +1,53 @@
|
||||
import AndroidLogo from '@/assets/icons/svg/android.svg';
|
||||
import AppleLogo from '@/assets/icons/svg/apple.svg';
|
||||
import MemoIP from '@/assets/icons/svg/memo-ip.svg';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Linking, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { AppDownload } from '@/components/download/app';
|
||||
import PCDownload from '@/components/download/pc';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Platform, Text, View } from 'react-native';
|
||||
|
||||
const IOS_APP_STORE_URL = 'https://apps.apple.com/cn/app/id6748205761';
|
||||
const ANDROID_APK_URL = 'https://cdn.memorywake.com/apks/application-f086a38c-dac1-43f1-9d24-e4378c2ce121.apk';
|
||||
export default function DownloadScreen() {
|
||||
const handleIOSDownload = () => {
|
||||
Linking.openURL(IOS_APP_STORE_URL);
|
||||
};
|
||||
|
||||
const handleAndroidDownload = () => {
|
||||
Linking.openURL(ANDROID_APK_URL);
|
||||
};
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [platform, setPlatform] = useState('')
|
||||
// 判断是什么平台
|
||||
const getPlatform = () => {
|
||||
let platform;
|
||||
if (Platform.OS === 'ios') {
|
||||
platform = 'ios';
|
||||
} else if (Platform.OS === 'android') {
|
||||
platform = 'android';
|
||||
} else {
|
||||
platform = 'pc';
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
|
||||
const { t } = useTranslation();
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
const platform = getPlatform();
|
||||
setPlatform(platform)
|
||||
setLoading(false)
|
||||
}, [])
|
||||
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<View className="flex-1 bg-bgPrimary justify-center items-center">
|
||||
<Text className="text-white">loading...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<LinearGradient
|
||||
colors={['#FFB645', '#E2793F']}
|
||||
className="flex-1 items-center justify-center p-6"
|
||||
>
|
||||
<View className="absolute top-0 left-0 w-full h-full">
|
||||
<MemoIP width="100%" height="100%" style={{ opacity: 0.1 }} />
|
||||
</View>
|
||||
<View className="items-center mb-12">
|
||||
<Text className="text-white text-5xl font-extrabold tracking-tight">
|
||||
MemoWake
|
||||
</Text>
|
||||
<Text className="text-white/90 text-lg mt-4 text-center max-w-xs">
|
||||
{t('desc', { ns: 'download' })}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
{
|
||||
platform === 'pc' && <PCDownload IOS_APP_STORE_URL={IOS_APP_STORE_URL} ANDROID_APK_URL={ANDROID_APK_URL} />
|
||||
}
|
||||
{
|
||||
(platform === 'ios' || platform === 'android') && (
|
||||
<AppDownload IOS_APP_STORE_URL={IOS_APP_STORE_URL} ANDROID_APK_URL={ANDROID_APK_URL} platform={platform} />
|
||||
)
|
||||
}
|
||||
</View>
|
||||
|
||||
<View className="w-full max-w-xs">
|
||||
<TouchableOpacity
|
||||
className="bg-white/90 rounded-xl px-6 py-4 flex-row items-center justify-center shadow-lg mb-5"
|
||||
onPress={handleIOSDownload}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<AppleLogo width={24} height={24} fill="black" />
|
||||
<Text className="text-black font-bold text-lg ml-3">
|
||||
{t('ios', { ns: 'download' })}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
className="bg-black/80 rounded-xl px-6 py-4 flex-row items-center justify-center shadow-lg"
|
||||
onPress={handleAndroidDownload}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<AndroidLogo width={24} height={24} fill="#3DDC84" />
|
||||
<Text className="text-white font-bold text-lg ml-3">
|
||||
{t('android', { ns: 'download' })}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
26
assets/icons/svg/logo.svg
Normal file
26
assets/icons/svg/logo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 952 KiB |
175
components/download/app.tsx
Normal file
175
components/download/app.tsx
Normal file
@ -0,0 +1,175 @@
|
||||
import HandlersSvg from "@/assets/icons/svg/handers.svg";
|
||||
import LogoSvg from "@/assets/icons/svg/logo.svg";
|
||||
import UserinfoTotalSvg from "@/assets/icons/svg/userinfoTotal.svg";
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Linking, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import QRDownloadScreen from "./qrCode";
|
||||
|
||||
interface AppDownloadProps {
|
||||
IOS_APP_STORE_URL: string,
|
||||
ANDROID_APK_URL: string,
|
||||
platform: string
|
||||
}
|
||||
|
||||
export const AppDownload = (props: AppDownloadProps) => {
|
||||
const { t } = useTranslation();
|
||||
const insets = useSafeAreaInsets();
|
||||
const { IOS_APP_STORE_URL, ANDROID_APK_URL, platform } = props
|
||||
const handleAppStoreDownload = () => {
|
||||
Linking.openURL(IOS_APP_STORE_URL);
|
||||
};
|
||||
|
||||
const handlePlayStoreDownload = () => {
|
||||
Linking.openURL(ANDROID_APK_URL);
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { paddingTop: insets.top }]}>
|
||||
{/* Main Content */}
|
||||
<View style={styles.content}>
|
||||
{/* App Icon */}
|
||||
<LogoSvg />
|
||||
|
||||
{/* App Name */}
|
||||
<Text style={styles.appName}>MemoWake</Text>
|
||||
{/* QRCode */}
|
||||
|
||||
<View style={styles.qrCodeContainer}>
|
||||
<UserinfoTotalSvg style={{ marginBottom: -20, zIndex: 1 }} />
|
||||
<HandlersSvg style={{ marginBottom: -4, zIndex: 3 }} />
|
||||
<View style={styles.qrCode}>
|
||||
<QRDownloadScreen url={platform == "ios" ? IOS_APP_STORE_URL : ANDROID_APK_URL} />
|
||||
</View>
|
||||
</View>
|
||||
{/* Description */}
|
||||
<Text style={styles.description}>
|
||||
{t('mobileDescription', { ns: 'download' })}
|
||||
</Text>
|
||||
|
||||
{/* Download Button */}
|
||||
<TouchableOpacity
|
||||
style={styles.downloadButton}
|
||||
onPress={Platform.OS === 'ios' ? handleAppStoreDownload : handlePlayStoreDownload}
|
||||
>
|
||||
<Text style={styles.downloadButtonText}>
|
||||
{t('download', { ns: 'download' })}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: 20,
|
||||
backgroundColor: '#FFB645'
|
||||
},
|
||||
qrCodeContainer: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
qrCodeBg: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
qrCode: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
borderRadius: 12,
|
||||
zIndex: 2,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
closeButton: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
closeButtonText: {
|
||||
color: '#fff',
|
||||
fontSize: 18,
|
||||
lineHeight: 24,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingBottom: 40,
|
||||
},
|
||||
appIconImage: {
|
||||
width: 100,
|
||||
height: 100
|
||||
},
|
||||
appIconText: {
|
||||
fontSize: 50,
|
||||
},
|
||||
appName: {
|
||||
fontSize: 32,
|
||||
fontWeight: 'bold',
|
||||
color: '#fff',
|
||||
marginBottom: 12,
|
||||
},
|
||||
description: {
|
||||
fontSize: 16,
|
||||
color: 'rgba(255, 255, 255, 0.9)',
|
||||
textAlign: 'center',
|
||||
marginBottom: 32,
|
||||
paddingHorizontal: 40,
|
||||
lineHeight: 24,
|
||||
marginVertical: 32
|
||||
},
|
||||
downloadButton: {
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 30,
|
||||
paddingVertical: 16,
|
||||
paddingHorizontal: 40,
|
||||
width: "90%",
|
||||
alignItems: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 4 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 8,
|
||||
elevation: 5,
|
||||
marginTop: 40
|
||||
},
|
||||
downloadButtonText: {
|
||||
color: '#4C320C',
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
badgesContainer: {
|
||||
alignItems: 'center',
|
||||
paddingBottom: 40,
|
||||
},
|
||||
availableOnText: {
|
||||
color: 'rgba(255, 255, 255, 0.8)',
|
||||
fontSize: 14,
|
||||
marginBottom: 12,
|
||||
},
|
||||
badgesRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
badgeButton: {
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 8,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 16,
|
||||
marginHorizontal: 8,
|
||||
minWidth: 120,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: 40,
|
||||
},
|
||||
badgeText: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
69
components/download/pc.tsx
Normal file
69
components/download/pc.tsx
Normal file
@ -0,0 +1,69 @@
|
||||
import AndroidLogo from '@/assets/icons/svg/android.svg';
|
||||
import AppleLogo from '@/assets/icons/svg/apple.svg';
|
||||
import MemoIP from '@/assets/icons/svg/memo-ip.svg';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Linking, Text, TouchableOpacity, View } from 'react-native';
|
||||
|
||||
interface PCDownloadProps {
|
||||
IOS_APP_STORE_URL: string,
|
||||
ANDROID_APK_URL: string
|
||||
}
|
||||
const PCDownload = (props: PCDownloadProps) => {
|
||||
const { IOS_APP_STORE_URL, ANDROID_APK_URL } = props
|
||||
|
||||
const handleIOSDownload = () => {
|
||||
Linking.openURL(IOS_APP_STORE_URL);
|
||||
};
|
||||
|
||||
const handleAndroidDownload = () => {
|
||||
Linking.openURL(ANDROID_APK_URL);
|
||||
};
|
||||
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<LinearGradient
|
||||
colors={['#FFB645', '#E2793F']}
|
||||
className="flex-1 items-center justify-center p-6"
|
||||
>
|
||||
<View className="absolute top-0 left-0 w-full h-full">
|
||||
<MemoIP width="100%" height="100%" style={{ opacity: 0.1 }} />
|
||||
</View>
|
||||
<View className="items-center mb-12">
|
||||
<Text className="text-white text-5xl font-extrabold tracking-tight">
|
||||
MemoWake
|
||||
</Text>
|
||||
<Text className="text-white/90 text-lg mt-4 text-center max-w-xs">
|
||||
{t('desc', { ns: 'download' })}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View className="w-full max-w-xs">
|
||||
<TouchableOpacity
|
||||
className="bg-white/90 rounded-xl px-6 py-4 flex-row items-center justify-center shadow-lg mb-5"
|
||||
onPress={handleIOSDownload}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<AppleLogo width={24} height={24} fill="black" />
|
||||
<Text className="text-black font-bold text-lg ml-3">
|
||||
{t('ios', { ns: 'download' })}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
className="bg-black/80 rounded-xl px-6 py-4 flex-row items-center justify-center shadow-lg"
|
||||
onPress={handleAndroidDownload}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<AndroidLogo width={24} height={24} fill="#3DDC84" />
|
||||
<Text className="text-white font-bold text-lg ml-3">
|
||||
{t('android', { ns: 'download' })}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default PCDownload
|
||||
71
components/download/qrCode.tsx
Normal file
71
components/download/qrCode.tsx
Normal file
@ -0,0 +1,71 @@
|
||||
import * as Haptics from 'expo-haptics';
|
||||
import * as MediaLibrary from 'expo-media-library';
|
||||
import React, { useRef } from 'react';
|
||||
import { Alert, 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') {
|
||||
Alert.alert('权限被拒绝', '需要保存图片到相册的权限');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qrViewRef.current) return;
|
||||
|
||||
// 截取二维码视图
|
||||
const uri = await captureRef(qrViewRef, {
|
||||
format: 'png',
|
||||
quality: 1,
|
||||
result: 'tmpfile', // 返回临时文件路径
|
||||
});
|
||||
|
||||
// 保存到相册
|
||||
await MediaLibrary.saveToLibraryAsync(uri);
|
||||
|
||||
Alert.alert('✅ 成功', '二维码已保存到相册!');
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error);
|
||||
Alert.alert('❌ 失败', '无法保存图片,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
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,
|
||||
},
|
||||
});
|
||||
@ -1,4 +1,5 @@
|
||||
import SettingSvg from '@/assets/icons/svg/setting.svg';
|
||||
import { useRouter } from 'expo-router';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { StyleProp, StyleSheet, TouchableOpacity, View, ViewStyle } from "react-native";
|
||||
import { ThemedText } from "../ThemedText";
|
||||
@ -9,9 +10,11 @@ interface CategoryProps {
|
||||
|
||||
const AlbumComponent = ({ setModalVisible, style }: CategoryProps) => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<View style={[styles.container, style]}>
|
||||
<TouchableOpacity style={{ flex: 3 }}>
|
||||
<TouchableOpacity style={{ flex: 3 }} onPress={() => { router.push("/download") }}>
|
||||
<ThemedText style={styles.text}>{t('generalSetting.album', { ns: 'personal' })}</ThemedText>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={{ flex: 3 }}>
|
||||
|
||||
@ -2,5 +2,7 @@
|
||||
"title": "Download Our App",
|
||||
"desc": "Get the full experience by downloading our app on your favorite platform.",
|
||||
"ios": "Download for iOS",
|
||||
"android": "Download for Android"
|
||||
"android": "Download for Android",
|
||||
"mobileDescription": "Scan the QR Code to awaken your precious memories",
|
||||
"download": "Download MemoWake"
|
||||
}
|
||||
@ -2,5 +2,7 @@
|
||||
"title": "下载我们的应用",
|
||||
"desc": "在您喜欢的平台上下载我们的应用,以获得完整的体验。",
|
||||
"ios": "下载 iOS 版",
|
||||
"android": "下载 Android 版"
|
||||
"android": "下载 Android 版",
|
||||
"mobileDescription": "扫描二维码唤醒珍贵记忆",
|
||||
"download": "下载 MemoWake"
|
||||
}
|
||||
309
package-lock.json
generated
309
package-lock.json
generated
@ -56,17 +56,20 @@
|
||||
"react-i18next": "^15.5.3",
|
||||
"react-native": "0.79.5",
|
||||
"react-native-gesture-handler": "~2.24.0",
|
||||
"react-native-linear-gradient": "^2.8.3",
|
||||
"react-native-modal": "^14.0.0-rc.1",
|
||||
"react-native-picker-select": "^9.3.1",
|
||||
"react-native-progress": "^5.0.1",
|
||||
"react-native-qrcode-svg": "^6.3.15",
|
||||
"react-native-reanimated": "~3.17.4",
|
||||
"react-native-reanimated-carousel": "^4.0.2",
|
||||
"react-native-render-html": "^6.3.4",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "~4.11.1",
|
||||
"react-native-svg": "15.11.2",
|
||||
"react-native-svg": "^15.11.2",
|
||||
"react-native-toast-message": "^2.3.0",
|
||||
"react-native-uuid": "^2.0.3",
|
||||
"react-native-view-shot": "4.0.3",
|
||||
"react-native-web": "~0.20.0",
|
||||
"react-native-webview": "13.13.5",
|
||||
"react-redux": "^9.2.0"
|
||||
@ -6148,6 +6151,15 @@
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
@ -7064,6 +7076,15 @@
|
||||
"hyphenate-style-name": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/css-line-break": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/css-select": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
|
||||
@ -7250,6 +7271,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/decode-uri-component": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
|
||||
@ -7421,6 +7451,12 @@
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dijkstrajs": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
|
||||
@ -9985,6 +10021,19 @@
|
||||
"void-elements": "3.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/html2canvas": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"css-line-break": "^2.1.0",
|
||||
"text-segmentation": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz",
|
||||
@ -14422,6 +14471,23 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/qrcode": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
|
||||
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"pngjs": "^5.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"bin": {
|
||||
"qrcode": "bin/qrcode"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode-terminal": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz",
|
||||
@ -14430,6 +14496,165 @@
|
||||
"qrcode-terminal": "bin/qrcode-terminal.js"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/qrcode/node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/pngjs": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
|
||||
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/qrcode/node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/query-string": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
|
||||
@ -14764,6 +14989,16 @@
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-linear-gradient": {
|
||||
"version": "2.8.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
|
||||
"integrity": "sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-modal": {
|
||||
"version": "14.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-14.0.0-rc.1.tgz",
|
||||
@ -14802,6 +15037,22 @@
|
||||
"react-native-svg": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-qrcode-svg": {
|
||||
"version": "6.3.15",
|
||||
"resolved": "https://registry.npmjs.org/react-native-qrcode-svg/-/react-native-qrcode-svg-6.3.15.tgz",
|
||||
"integrity": "sha512-vLuNImGfstE8u+rlF4JfFpq65nPhmByuDG6XUPWh8yp8MgLQX11rN5eQ8nb/bf4OB+V8XoLTJB/AZF2g7jQSSQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.0",
|
||||
"qrcode": "^1.5.4",
|
||||
"text-encoding": "^0.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": ">=0.63.4",
|
||||
"react-native-svg": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-reanimated": {
|
||||
"version": "3.17.5",
|
||||
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.17.5.tgz",
|
||||
@ -14947,6 +15198,19 @@
|
||||
"npm": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-view-shot": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-view-shot/-/react-native-view-shot-4.0.3.tgz",
|
||||
"integrity": "sha512-USNjYmED7C0me02c1DxKA0074Hw+y/nxo+xJKlffMvfUWWzL5ELh/TJA/pTnVqFurIrzthZDPtDM7aBFJuhrHQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"html2canvas": "^1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-web": {
|
||||
"version": "0.20.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.20.0.tgz",
|
||||
@ -15289,6 +15553,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/requireg": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/requireg/-/requireg-0.2.2.tgz",
|
||||
@ -15804,6 +16074,12 @@
|
||||
"integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
@ -16771,6 +17047,22 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/text-encoding": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz",
|
||||
"integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==",
|
||||
"deprecated": "no longer maintained",
|
||||
"license": "(Unlicense OR Apache-2.0)"
|
||||
},
|
||||
"node_modules/text-segmentation": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/thenify": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
||||
@ -17445,6 +17737,15 @@
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/utrie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
|
||||
@ -17660,6 +17961,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/which-module": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
|
||||
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.19",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
|
||||
|
||||
@ -62,20 +62,23 @@
|
||||
"react-i18next": "^15.5.3",
|
||||
"react-native": "0.79.5",
|
||||
"react-native-gesture-handler": "~2.24.0",
|
||||
"react-native-linear-gradient": "^2.8.3",
|
||||
"react-native-modal": "^14.0.0-rc.1",
|
||||
"react-native-picker-select": "^9.3.1",
|
||||
"react-native-progress": "^5.0.1",
|
||||
"react-native-qrcode-svg": "^6.3.15",
|
||||
"react-native-reanimated": "~3.17.4",
|
||||
"react-native-reanimated-carousel": "^4.0.2",
|
||||
"react-native-render-html": "^6.3.4",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "~4.11.1",
|
||||
"react-native-svg": "15.11.2",
|
||||
"react-native-svg": "^15.11.2",
|
||||
"react-native-toast-message": "^2.3.0",
|
||||
"react-native-uuid": "^2.0.3",
|
||||
"react-native-web": "~0.20.0",
|
||||
"react-native-webview": "13.13.5",
|
||||
"react-redux": "^9.2.0"
|
||||
"react-redux": "^9.2.0",
|
||||
"react-native-view-shot": "4.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user