feat: 隐私协议 (#10)
All checks were successful
Dev Deploy / Explore-Gitea-Actions (push) Successful in 28s

Reviewed-on: #10
This commit is contained in:
jinyaqiu 2025-07-21 20:35:10 +08:00
parent a764210a61
commit a8c5117cb7
2 changed files with 170 additions and 1 deletions

View File

@ -3,12 +3,12 @@ import { TabBarIcon } from '@/components/navigation/TabBarIcon';
import TabBarBackground from '@/components/ui/TabBarBackground'; import TabBarBackground from '@/components/ui/TabBarBackground';
import { Colors } from '@/constants/Colors'; import { Colors } from '@/constants/Colors';
import { useColorScheme } from '@/hooks/useColorScheme'; import { useColorScheme } from '@/hooks/useColorScheme';
import { useTranslation } from 'react-i18next';
import { fetchApi } from '@/lib/server-api-util'; import { fetchApi } from '@/lib/server-api-util';
import * as Notifications from 'expo-notifications'; import * as Notifications from 'expo-notifications';
import { Tabs } from 'expo-router'; import { Tabs } from 'expo-router';
import * as SecureStore from 'expo-secure-store'; import * as SecureStore from 'expo-secure-store';
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Platform } from 'react-native'; import { Platform } from 'react-native';
interface PollingData { interface PollingData {
@ -282,6 +282,16 @@ export default function TabLayout() {
tabBarStyle: { display: 'none' } // 确保在标签栏中不显示 tabBarStyle: { display: 'none' } // 确保在标签栏中不显示
}} }}
/> />
{/* 隐私协议 */}
<Tabs.Screen
name="privacy-policy"
options={{
title: 'privacy-policy',
tabBarButton: () => null, // 隐藏底部标签栏
headerShown: false, // 隐藏导航栏
tabBarStyle: { display: 'none' } // 确保在标签栏中不显示
}}
/>
{/* Support Screen */} {/* Support Screen */}
<Tabs.Screen <Tabs.Screen

View File

@ -0,0 +1,159 @@
import { fetchApi } from "@/lib/server-api-util";
import { Policy } from "@/types/personal-info";
import { useEffect, useState } from "react";
import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
import RenderHtml from 'react-native-render-html';
const PrivacyPolicy = () => {
const [article, setArticle] = useState<Policy>({} as Policy);
useEffect(() => {
const loadArticle = async () => {
fetchApi<Policy>(`/system-config/policy/privacy_policy`).then((res: any) => {
setArticle(res)
}).catch((error: any) => {
console.log(error)
})
}
loadArticle();
}, []);
if (!article) {
return (
<View style={styles.container}>
<Text>...</Text>
</View>
);
}
return (
<View style={styles.centeredView}>
<View style={styles.modalView}>
<View style={styles.modalHeader}>
<Text style={{ opacity: 0 }}>Settings</Text>
<Text style={styles.modalTitle}>{'Privacy Policy'}</Text>
<TouchableOpacity style={{ opacity: 0 }}>
<Text style={styles.closeButton}>×</Text>
</TouchableOpacity>
</View>
<ScrollView style={styles.modalContent} showsVerticalScrollIndicator={false}>
<RenderHtml
source={{ html: article.content }}
tagsStyles={{
p: { fontSize: 16, lineHeight: 24 },
strong: { fontWeight: 'bold' },
em: { fontStyle: 'italic' },
}}
/>
</ScrollView>
</View>
</View>
);
};
export default PrivacyPolicy;
const styles = StyleSheet.create({
centeredView: {
flex: 1,
justifyContent: 'flex-end',
backgroundColor: 'rgba(0,0,0,0.5)',
},
container: {
flex: 1,
},
modalView: {
width: '100%',
height: '100%',
backgroundColor: 'white',
paddingHorizontal: 16,
},
modalHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 20,
},
modalTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#4C320C',
},
closeButton: {
fontSize: 28,
color: '#4C320C',
padding: 10,
},
modalContent: {
flex: 1,
},
modalText: {
fontSize: 16,
color: '#4C320C',
},
premium: {
backgroundColor: "#FAF9F6",
padding: 16,
borderRadius: 24,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
content: {
flex: 1,
flexDirection: 'column',
gap: 4,
backgroundColor: '#FAF9F6',
borderRadius: 24,
paddingVertical: 8
},
item: {
paddingHorizontal: 16,
paddingVertical: 8,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
itemText: {
fontSize: 14,
fontWeight: '600',
color: '#4C320C',
},
upgradeButton: {
backgroundColor: '#E2793F',
borderRadius: 20,
paddingHorizontal: 16,
paddingVertical: 8,
},
upgradeButtonText: {
color: '#fff',
fontSize: 14,
fontWeight: "600"
},
switchContainer: {
width: 50,
height: 30,
borderRadius: 15,
justifyContent: 'center',
paddingHorizontal: 2,
},
switchOn: {
backgroundColor: '#E2793F',
alignItems: 'flex-end',
},
switchOff: {
backgroundColor: '#E5E5E5',
alignItems: 'flex-start',
},
switchCircle: {
width: 26,
height: 26,
borderRadius: 13,
},
switchCircleOn: {
backgroundColor: 'white',
},
switchCircleOff: {
backgroundColor: '#A5A5A5',
},
});