feat: 优化
This commit is contained in:
parent
12fce0021a
commit
a0c1f0e8b6
@ -9,12 +9,14 @@ import { ThemedText } from '@/components/ThemedText';
|
||||
import { fetchApi } from '@/lib/server-api-util';
|
||||
import { useLocalSearchParams, useRouter } from "expo-router";
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Image, ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native';
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
|
||||
export default function Rights() {
|
||||
const insets = useSafeAreaInsets();
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
// 获取路由参数
|
||||
const { credit } = useLocalSearchParams<{
|
||||
credit: string;
|
||||
@ -53,7 +55,7 @@ export default function Rights() {
|
||||
<ReturnArrowSvg />
|
||||
</TouchableOpacity>
|
||||
<ThemedText style={styles.headerTitle}>
|
||||
Subscription
|
||||
{t('rights.title', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
<ThemedText className='opacity-0'>123</ThemedText>
|
||||
</View>
|
||||
@ -67,7 +69,7 @@ export default function Rights() {
|
||||
<View style={styles.cardContent}>
|
||||
<View style={styles.cardinfo}>
|
||||
<ThemedText style={styles.cardTitle}>
|
||||
Purchase
|
||||
{t('rights.purchase', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
<View style={styles.cardPoints}>
|
||||
<StarSvg />
|
||||
@ -85,13 +87,13 @@ export default function Rights() {
|
||||
onPress={() => { setUserType("normal") }}
|
||||
style={[styles.switchButtonItem, { backgroundColor: userType === 'normal' ? "#FFB645" : "#fff", borderColor: userType === 'normal' ? "#FFB645" : "#E2793F" }]}
|
||||
>
|
||||
<ThemedText style={{ color: userType === 'normal' ? "#fff" : "#E2793F" }}>Free</ThemedText>
|
||||
<ThemedText style={{ color: userType === 'normal' ? "#fff" : "#E2793F" }}> {t('rights.free', { ns: 'personal' })}</ThemedText>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={() => { setUserType("premium") }}
|
||||
style={[styles.switchButtonItem, { backgroundColor: userType === 'premium' ? "#E2793F" : "#fff", borderColor: userType === 'premium' ? "#E2793F" : "#E2793F" }]}
|
||||
>
|
||||
<ThemedText style={{ color: userType === 'premium' ? "#fff" : "#E2793F" }}>Pro</ThemedText>
|
||||
<ThemedText style={{ color: userType === 'premium' ? "#fff" : "#E2793F" }}>{t('rights.premium', { ns: 'personal' })}</ThemedText>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{/* 普通权益 */}
|
||||
@ -124,7 +126,7 @@ export default function Rights() {
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<ThemedText style={{ color: '#fff', fontWeight: '700', fontSize: 14 }}>
|
||||
Subscribe Yearly
|
||||
{t('rights.subscribe', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
@ -134,7 +136,7 @@ export default function Rights() {
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<ThemedText style={{ color: '#AC7E35', fontWeight: '400', fontSize: 11, textDecorationLine: 'underline', textAlign: 'center' }}>
|
||||
Terms • Privacy
|
||||
{t('rights.terms', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@ -16,7 +16,7 @@ import * as Location from 'expo-location';
|
||||
import { useRouter } from 'expo-router';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Linking, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { Linking, Platform, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
|
||||
const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: boolean) => void, userInfo: User }) => {
|
||||
@ -98,11 +98,9 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
|
||||
try {
|
||||
// 1. 首先检查当前权限状态 -- 获取当前的位置权限
|
||||
let currentStatus = await getLocationPermission();
|
||||
console.log('当前权限状态:', currentStatus);
|
||||
|
||||
// 2. 如果没有权限,则跳过获取位置
|
||||
if (!currentStatus) {
|
||||
console.log('没有权限,跳过获取位置')
|
||||
return;
|
||||
// const newStatus = await requestLocationPermission();
|
||||
// setLocationEnabled(newStatus);
|
||||
@ -117,16 +115,14 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
|
||||
// 3. 确保位置服务已启用
|
||||
const isEnabled = await Location.hasServicesEnabledAsync();
|
||||
if (!isEnabled) {
|
||||
alert('请先启用位置服务');
|
||||
alert(t('permission.locationPermissionRequired', { ns: 'common' }));
|
||||
return;
|
||||
}
|
||||
console.log('位置服务已启用');
|
||||
// 4. 获取当前位置
|
||||
const location = await Location.getCurrentPositionAsync({
|
||||
accuracy: Location.Accuracy.High, // 使用高精度
|
||||
timeInterval: 10000, // 可选:最大等待时间(毫秒)
|
||||
});
|
||||
console.log('位置:', location);
|
||||
|
||||
// 地理位置逆编码
|
||||
const address = await reverseGeocode(location.coords.latitude, location.coords.longitude);
|
||||
@ -137,12 +133,10 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
|
||||
|
||||
return location;
|
||||
} catch (error: any) {
|
||||
if (error.code === 'PERMISSION_DENIED' || error.code === 'PERMISSION_DENIED_ERROR') {
|
||||
alert('位置权限被拒绝,请在设置中启用位置服务');
|
||||
} else if (error.code === 'TIMEOUT') {
|
||||
alert('获取位置超时,请检查网络和位置服务');
|
||||
if (error.code === 'TIMEOUT') {
|
||||
alert(t('permission.timeout', { ns: 'common' }));
|
||||
} else {
|
||||
alert(`无法获取您的位置: ${error.message || '未知错误'}`);
|
||||
alert(t('permission.notLocation', { ns: 'common' }) + error.message || t('permission.notError', { ns: 'common' }));
|
||||
}
|
||||
throw error; // 重新抛出错误以便上层处理
|
||||
} finally {
|
||||
@ -173,17 +167,14 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
|
||||
if (modalVisible) {
|
||||
// 位置权限
|
||||
getLocationPermission().then((res: boolean | ((prevState: boolean) => boolean)) => {
|
||||
console.log('位置权限:', res);
|
||||
setLocationEnabled(res);
|
||||
})
|
||||
// 媒体库权限
|
||||
getPermissions().then((res: boolean | ((prevState: boolean) => boolean)) => {
|
||||
console.log('媒体库权限:', res);
|
||||
setAlbumEnabled(res);
|
||||
})
|
||||
// 通知权限
|
||||
checkNotificationPermission().then((res: boolean | ((prevState: boolean) => boolean)) => {
|
||||
console.log('通知权限:', res);
|
||||
setNotificationsEnabled(res);
|
||||
})
|
||||
}
|
||||
@ -344,8 +335,8 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
|
||||
<RightArrowSvg />
|
||||
</TouchableOpacity>
|
||||
<Divider />
|
||||
<TouchableOpacity style={styles.item} onPress={() => Linking.openURL("https://beian.miit.gov.cn/")} >
|
||||
<ThemedText style={styles.itemText}>{t('lcenses.ICP', { ns: 'personal' })}沪ICP备2023032876号-4</ThemedText>
|
||||
<TouchableOpacity style={[styles.item, { display: Platform.OS === 'ios' ? 'none' : 'flex' }]} onPress={() => Linking.openURL("https://beian.miit.gov.cn/")} >
|
||||
<ThemedText style={styles.itemText}>{t('lcenses.ICP', { ns: 'personal' })}沪ICP备2025133004号-2A</ThemedText>
|
||||
<RightArrowSvg />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import GetSvg from "@/assets/icons/svg/get.svg";
|
||||
import { ThemedText } from "@/components/ThemedText";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { StyleProp, StyleSheet, TouchableOpacity, View, ViewStyle } from "react-native";
|
||||
|
||||
interface Props {
|
||||
@ -9,6 +10,7 @@ interface Props {
|
||||
|
||||
const Normal = (props: Props) => {
|
||||
const { setUserType } = props;
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<View style={[styles.normalInfo, props.style]}>
|
||||
@ -16,16 +18,16 @@ const Normal = (props: Props) => {
|
||||
<View style={styles.normalItemContent}>
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
||||
<GetSvg style={{ marginTop: 8 }} />
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>Enjoy 100 Bonus Credits Every Month</ThemedText>
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>{t('rights.100Bonus', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>Generate more memory pictures & videos and explore your past.</ThemedText>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>{t('rights.100BonusText', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
<View style={styles.normalItemContent}>
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
||||
<GetSvg style={{ marginTop: 8 }} />
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>10GB of Cloud Storage</ThemedText>
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>{t('rights.10G', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>Safely store your cherished photos, videos, and generated memories.</ThemedText>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>{t('rights.10GText', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
@ -36,7 +38,7 @@ const Normal = (props: Props) => {
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<ThemedText style={{ color: '#fff', fontWeight: '700', fontSize: 14 }}>
|
||||
Go Premium
|
||||
{t('rights.purchase', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import BlackStarSvg from '@/assets/icons/svg/blackStar.svg';
|
||||
import { ThemedText } from "@/components/ThemedText";
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ScrollView, StyleProp, StyleSheet, TouchableOpacity, View, ViewStyle } from "react-native";
|
||||
import { maxDiscountProduct } from './utils';
|
||||
|
||||
@ -31,6 +32,7 @@ export interface PayItem {
|
||||
const Premium = (props: Props) => {
|
||||
const { style, payType, setPayType, premiumPay, loading, setShowTerms } = props;
|
||||
const bestValue = maxDiscountProduct(premiumPay)?.product_code
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<View style={[styles.proInfo, style]}>
|
||||
@ -43,7 +45,7 @@ const Premium = (props: Props) => {
|
||||
{loading
|
||||
?
|
||||
<ThemedText style={{ fontSize: 12, color: "#4C320C", fontWeight: "700", width: "100%", textAlign: "center" }}>
|
||||
Loading...
|
||||
{t('loading', { ns: 'common' })}
|
||||
</ThemedText>
|
||||
:
|
||||
premiumPay?.map((item: PayItem) => {
|
||||
@ -57,7 +59,7 @@ const Premium = (props: Props) => {
|
||||
<View style={[styles.title, { opacity: item?.product_code === bestValue ? 1 : 0 }]}>
|
||||
<BlackStarSvg />
|
||||
<ThemedText style={[styles.titleText, { fontSize: 14 }]}>
|
||||
Best Value
|
||||
{t('rights.bestValue', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
<BlackStarSvg />
|
||||
</View>
|
||||
@ -78,10 +80,10 @@ const Premium = (props: Props) => {
|
||||
</ScrollView>
|
||||
<View style={{ flexDirection: 'row', gap: 8, marginLeft: 4 }}>
|
||||
<ThemedText style={{ color: '#AC7E35', fontSize: 10 }}>
|
||||
Cancel anytime before renewal. Learn more
|
||||
{t('rights.cancelAnytimeBeforeRenewal', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
<ThemedText style={{ color: '#E2793F', fontSize: 10, textDecorationLine: 'underline' }} onPress={() => setShowTerms(true)}>
|
||||
Terms & Conditions
|
||||
{t('rights.terms', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@ -1,33 +1,35 @@
|
||||
import GetSvg from "@/assets/icons/svg/get.svg";
|
||||
import { ThemedText } from "@/components/ThemedText";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { StyleProp, StyleSheet, View, ViewStyle } from "react-native";
|
||||
const ProRights = (props: { style?: StyleProp<ViewStyle> }) => {
|
||||
const { style } = props;
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<View style={[styles.proRights, style]}>
|
||||
<ThemedText style={{ fontSize: 12, color: "#4C320C", fontWeight: "700", width: "100%", textAlign: "center" }}>
|
||||
Enjoy MemoWake Pro Benefits
|
||||
{t('rights.proTitle', { ns: 'personal' })}
|
||||
</ThemedText>
|
||||
<View style={{ display: "flex", flexDirection: "column", }}>
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
||||
<GetSvg style={{ marginTop: 8 }} />
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>no advertisement</ThemedText>
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>{t('rights.noAd', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>There are no advertisements, so you can use the product with peace of mind.</ThemedText>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>{t('rights.noAdText', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
<View style={styles.itemContent}>
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
||||
<GetSvg style={{ marginTop: 8 }} />
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>Enjoy 1000 Bonus Credits Every Month</ThemedText>
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>{t('rights.bonus', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>Generate more memory pictures & videos and explore your past.</ThemedText>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>{t('rights.bonusText', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
<View style={styles.itemContent}>
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
||||
<GetSvg style={{ marginTop: 8 }} />
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>100GB of Cloud Storage</ThemedText>
|
||||
<ThemedText style={{ fontSize: 12, fontWeight: '500', color: "#4C320C" }}>{t('rights.storage', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>Safely store your cherished photos, videos, and generated memories.</ThemedText>
|
||||
<ThemedText style={{ fontSize: 10, color: "#AC7E35", marginLeft: 20 }}>{t('rights.storageText', { ns: 'personal' })}</ThemedText>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@ -111,5 +111,11 @@
|
||||
"required": "You must agree to the Terms and Privacy Policy"
|
||||
}
|
||||
},
|
||||
"loading": "Loading..."
|
||||
"loading": "Loading...",
|
||||
"permission": {
|
||||
"locationPermissionRequired": "Location permission is required, please enable location service in settings",
|
||||
"timeout": "Location timeout, please check network and location service",
|
||||
"notLocation": "Unable to get your location: ",
|
||||
"notError": "Unknown error"
|
||||
}
|
||||
}
|
||||
@ -88,5 +88,27 @@
|
||||
"unlock": "Unlock more memory magic",
|
||||
"delete": "Are you sure you want to delete your account?",
|
||||
"cancel": "Cancel"
|
||||
},
|
||||
"rights": {
|
||||
"title": "Subscription",
|
||||
"premium": "Pro",
|
||||
"purchase": "Purchase",
|
||||
"free": "Free",
|
||||
"subscribe": "Subscribe",
|
||||
"terms": "Terms",
|
||||
"100Bonus": "Enjoy 100 Bonus Credits Every Month",
|
||||
"100BonusText": "Generate more memory pictures & videos and explore your past.",
|
||||
"10G": "10GB of Cloud Storage",
|
||||
"10GText": "Safely store your cherished photos, videos, and generated memories.",
|
||||
"goPremium": "Go Premium",
|
||||
"bestValue": "Best Value",
|
||||
"cancelAnytimeBeforeRenewal": "Cancel anytime before renewal. Learn more",
|
||||
"proTitle": "Enjoy MemoWake Pro Benefits",
|
||||
"noAd": "No advertisements",
|
||||
"noAdText": "There are no advertisements, so you can use the product with peace of mind.",
|
||||
"bonus": "Enjoy 100 Bonus Credits Every Month",
|
||||
"bonusText": "Generate more memory pictures & videos and explore your past.",
|
||||
"storage": "10GB of Cloud Storage",
|
||||
"storageText": "Safely store your cherished photos, videos, and generated memories."
|
||||
}
|
||||
}
|
||||
@ -110,5 +110,11 @@
|
||||
"required": "您必须同意服务条款和隐私政策"
|
||||
}
|
||||
},
|
||||
"loading": "加载中..."
|
||||
"loading": "加载中...",
|
||||
"permission": {
|
||||
"locationPermissionRequired": "位置权限被拒绝,请在设置中启用位置服务",
|
||||
"timeout": "获取位置超时,请检查网络和位置服务",
|
||||
"notLocation": "无法获取您的位置: ",
|
||||
"notError": "未知错误"
|
||||
}
|
||||
}
|
||||
@ -88,5 +88,27 @@
|
||||
"unlock": "解锁更多记忆魔法",
|
||||
"delete": "确定要注销账号吗?",
|
||||
"cancel": "取消"
|
||||
},
|
||||
"rights": {
|
||||
"title": "权益",
|
||||
"purchase": "购买",
|
||||
"free": "免费用户",
|
||||
"premium": "会员",
|
||||
"subscribe": "订阅",
|
||||
"terms": "用户协议",
|
||||
"100Bonus": "每月享受100积分",
|
||||
"100BonusText": "生成更多记忆照片和视频,探索你的过去。",
|
||||
"10G": "10GB的云存储",
|
||||
"10GText": "安全存储你的珍贵照片、视频和生成的记忆。",
|
||||
"goPremium": "升级至会员",
|
||||
"bestValue": "最佳值",
|
||||
"cancelAnytimeBeforeRenewal": "在续订前随时取消。了解更多",
|
||||
"proTitle": "享受MemoWake Pro权益",
|
||||
"noAd": "无广告",
|
||||
"noAdText": "没有广告,所以你可以安心使用产品。",
|
||||
"bonus": "每月享受100积分",
|
||||
"bonusText": "生成更多记忆照片和视频,探索你的过去。",
|
||||
"storage": "10GB的云存储",
|
||||
"storageText": "安全存储你的珍贵照片、视频和生成的记忆。"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user