PrivacyPopup.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import AsyncStorage from "@react-native-async-storage/async-storage";
  2. import { usePathname, useRouter } from "expo-router";
  3. import React, { useEffect, useState } from "react";
  4. import {
  5. BackHandler,
  6. Platform,
  7. ScrollView,
  8. StyleSheet,
  9. Text,
  10. TouchableOpacity,
  11. View,
  12. } from "react-native";
  13. export function PrivacyPopup() {
  14. const [agreed, setAgreed] = useState<boolean | null>(null);
  15. const router = useRouter();
  16. const pathname = usePathname();
  17. useEffect(() => {
  18. checkPrivacyStatus();
  19. }, []);
  20. const checkPrivacyStatus = async () => {
  21. try {
  22. const status = await AsyncStorage.getItem("hasAgreedPrivacy");
  23. setAgreed(status === "true");
  24. } catch (e) {
  25. setAgreed(false);
  26. }
  27. };
  28. const handleAgree = async () => {
  29. try {
  30. await AsyncStorage.setItem("hasAgreedPrivacy", "true");
  31. setAgreed(true);
  32. } catch (e) {
  33. console.warn("Failed to save privacy status");
  34. }
  35. };
  36. const handleDisagree = () => {
  37. if (Platform.OS === "android") {
  38. BackHandler.exitApp();
  39. }
  40. };
  41. const openUserAgreement = () => {
  42. router.push({ pathname: "/agreement", params: { type: "user.html" } });
  43. };
  44. const openPrivacyPolicy = () => {
  45. router.push({ pathname: "/agreement", params: { type: "privacy.html" } });
  46. };
  47. if (agreed === null || agreed === true) {
  48. return null;
  49. }
  50. // 隐藏弹窗以允许查看协议
  51. if (pathname === "/agreement") {
  52. return null;
  53. }
  54. return (
  55. <View style={styles.overlay}>
  56. <View style={styles.container}>
  57. <Text style={styles.title}>个人信息保护指引</Text>
  58. <ScrollView style={styles.scroll}>
  59. <Text style={styles.content}>
  60. 感谢您使用我们要提供给您的服务!我们非常重视您的个人信息和隐私保护。在您使用我们的服务之前,请务必仔细阅读
  61. <Text style={styles.link} onPress={openUserAgreement}>
  62. 《用户协议》
  63. </Text>
  64. <Text style={styles.link} onPress={openPrivacyPolicy}>
  65. 《隐私政策》
  66. </Text>
  67. 。{"\n\n"}
  68. 我们将严格按照上述协议/政策为您提供服务,保护您的个人信息安全。如果您同意以上内容,请点击“同意”开始使用。
  69. </Text>
  70. </ScrollView>
  71. <View style={styles.btnRow}>
  72. <TouchableOpacity
  73. style={styles.disagreeBtn}
  74. onPress={handleDisagree}
  75. activeOpacity={0.8}
  76. >
  77. <Text style={styles.disagreeText}>不同意并退出</Text>
  78. </TouchableOpacity>
  79. <TouchableOpacity
  80. style={styles.agreeBtn}
  81. onPress={handleAgree}
  82. activeOpacity={0.8}
  83. >
  84. <Text style={styles.agreeText}>同意</Text>
  85. </TouchableOpacity>
  86. </View>
  87. </View>
  88. </View>
  89. );
  90. }
  91. const styles = StyleSheet.create({
  92. overlay: {
  93. position: "absolute",
  94. top: 0,
  95. left: 0,
  96. right: 0,
  97. bottom: 0,
  98. backgroundColor: "rgba(0,0,0,0.6)",
  99. justifyContent: "center",
  100. alignItems: "center",
  101. padding: 30,
  102. zIndex: 9999,
  103. elevation: 9999,
  104. },
  105. container: {
  106. width: "100%",
  107. backgroundColor: "#fff",
  108. borderRadius: 12,
  109. padding: 24,
  110. maxHeight: "70%",
  111. },
  112. title: {
  113. fontSize: 18,
  114. fontWeight: "bold",
  115. color: "#333",
  116. textAlign: "center",
  117. marginBottom: 15,
  118. },
  119. scroll: {
  120. maxHeight: 250,
  121. },
  122. content: {
  123. fontSize: 14,
  124. color: "#666",
  125. lineHeight: 22,
  126. },
  127. link: {
  128. color: "#8b3dff",
  129. },
  130. btnRow: {
  131. flexDirection: "row",
  132. justifyContent: "space-between",
  133. marginTop: 20,
  134. },
  135. disagreeBtn: {
  136. flex: 1,
  137. paddingVertical: 12,
  138. alignItems: "center",
  139. backgroundColor: "#f5f5f5",
  140. borderRadius: 20,
  141. marginRight: 10,
  142. },
  143. disagreeText: {
  144. color: "#999",
  145. fontSize: 14,
  146. },
  147. agreeBtn: {
  148. flex: 1,
  149. paddingVertical: 12,
  150. alignItems: "center",
  151. backgroundColor: "#8b3dff",
  152. borderRadius: 20,
  153. marginLeft: 10,
  154. },
  155. agreeText: {
  156. color: "#fff",
  157. fontSize: 14,
  158. fontWeight: "bold",
  159. },
  160. });