import React, { useState, useRef } from "react"; import { View, Text, StyleSheet, TouchableOpacity, TextInput, FlatList, Keyboard, Alert, Platform, Modal } from "react-native"; import { useTranslation } from "react-i18next"; import { useNavigation } from "@react-navigation/native"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { userApi } from "../../services/api/userApi"; import { settingApi } from "../../services/api/setting"; import useUserStore from "../../store/user"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; // Common email domains list const EMAIL_DOMAINS = [ "gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "icloud.com", "mail.com", "protonmail.com", "qq.com", "163.com", "126.com", ]; type RootStackParamList = { Login: undefined; EmailLogin: undefined; MainTabs: { screen: string }; Google: undefined; Home: { screen: string }; }; type EmailLoginModalProps = { visible: boolean; onClose: () => void; }; const EmailLoginModal = ({ visible, onClose }: EmailLoginModalProps) => { const { t } = useTranslation(); const navigation = useNavigation>(); const { setSettings, setUser } = useUserStore(); // 状态管理 const [email, setEmail] = useState(""); const [emailPassword, setEmailPassword] = useState(""); const [emailPasswordError, setEmailPasswordError] = useState(false); const [showSuggestions, setShowSuggestions] = useState(false); const [suggestions, setSuggestions] = useState([]); // 防止重复关闭 const isClosing = useRef(false); // 引用输入框 const emailInputRef = useRef(null); const passwordInputRef = useRef(null); // 主动弹出键盘 const focusEmailInput = () => { if (emailInputRef.current) { emailInputRef.current.focus(); } }; const focusPasswordInput = () => { if (passwordInputRef.current) { passwordInputRef.current.focus(); } }; React.useEffect(() => { if (visible) { // 当模态框显示时,等待动画完成后主动弹出键盘 const timer = setTimeout(() => { focusEmailInput(); }, 300); return () => clearTimeout(timer); } }, [visible]); // 处理邮箱输入变化 const handleEmailChange = (text: string) => { setEmail(text); // Check if it includes @ symbol if (text.includes("@")) { const [username, domain] = text.split("@"); if (domain) { // If domain part is already entered, filter matching domains const filteredDomains = EMAIL_DOMAINS.filter((item) => item.toLowerCase().startsWith(domain.toLowerCase()) ); // Generate complete email suggestion list const emailSuggestions = filteredDomains.map((d) => `${username}@${d}`); setSuggestions(emailSuggestions); setShowSuggestions(emailSuggestions.length > 0); } else { // If only @ is entered, show all domain suggestions const emailSuggestions = EMAIL_DOMAINS.map((d) => `${username}@${d}`); setSuggestions(emailSuggestions); setShowSuggestions(true); } } else if (text.length > 0) { // No @ symbol but has input content, show common email suffix suggestions const emailSuggestions = EMAIL_DOMAINS.map((d) => `${text}@${d}`); setSuggestions(emailSuggestions); setShowSuggestions(true); } else { // Empty input, don't show suggestions setShowSuggestions(false); } }; // Select an email suggestion const handleSelectSuggestion = (suggestion: string) => { setEmail(suggestion); setShowSuggestions(false); }; // Validate email format const isValidEmail = (email: string): boolean => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); }; // Render a single email suggestion item const renderSuggestionItem = ({ item }: { item: string }) => ( handleSelectSuggestion(item)} > {item} ); // Handle forgot password const handleForgotPassword = () => { // Handle forgot password logic }; // Handle email login const handleEmailContinue = async () => { const params = { grant_type: "password", username: "lifei", password: "123456", client_id: "2", client_secret: "", scope: "", }; try { const res = await userApi.login(params); if (res.access_token) { const token = res.token_type + " " + res.access_token; await AsyncStorage.setItem("token", token); const data = await settingApi.postFirstLogin(221); setSettings(data); const user = await userApi.getProfile(); setUser(user); navigation.navigate("MainTabs", { screen: "Home" }); onClose(); } } catch (error) { Alert.alert(t("loginFailed")); } }; // 安全地关闭模态框 const closeEmailLogin = () => { console.log("Closing email login modal"); // 确保键盘关闭 Keyboard.dismiss(); // 直接调用关闭回调 onClose(); }; return ( onClose()} statusBarTranslucent={true} > onClose()} activeOpacity={0.7} > {t("logInOrSignUp")} { handleEmailChange(text); setEmailPasswordError(false); }} keyboardType="email-address" autoCapitalize="none" autoCorrect={false} autoFocus maxLength={50} /> {email.length > 0 ? ( { setEmail(""); setShowSuggestions(false); setEmailPasswordError(false); }} activeOpacity={0.7} > ) : ( ⌨️ )} {/* Email suffix suggestion list */} {showSuggestions && ( item} style={styles.suggestionsList} keyboardShouldPersistTaps="handled" removeClippedSubviews={true} initialNumToRender={5} maxToRenderPerBatch={5} windowSize={5} getItemLayout={(data, index) => ({ length: 44, offset: 44 * index, index, })} /> )} {/* Password input */} { setEmailPassword(text); setEmailPasswordError(false); }} secureTextEntry={true} autoCapitalize="none" /> {emailPasswordError ? ( ! ) : ( ⌨️ )} {/* Password error message */} {emailPasswordError && ( <> {t("passwordIncorrect")} {t("forgotPassword")} )} {t("continue")} ); }; const styles = StyleSheet.create({ modalContainer: { flex: 1, backgroundColor: "rgba(0, 0, 0, 0.5)", justifyContent: "flex-end", zIndex: 999, }, emailLoginContainer: { backgroundColor: "#fff", borderTopLeftRadius: 20, borderTopRightRadius: 20, height: "80%", shadowColor: "#000", shadowOffset: { width: 0, height: -2 }, shadowOpacity: 0.1, shadowRadius: 5, elevation: 5, }, emailLoginHeader: { flexDirection: "row", alignItems: "center", paddingTop: 20, paddingHorizontal: 16, paddingBottom: 15, borderBottomWidth: 1, borderBottomColor: "#f0f0f0", }, emailLoginCloseButton: { padding: 8, width: 36, height: 36, justifyContent: "center", alignItems: "center", }, emailLoginCloseButtonText: { fontSize: 18, color: "#000", }, emailLoginTitle: { flex: 1, fontSize: 18, fontWeight: "600", color: "#000", textAlign: "center", marginRight: 36, }, emailLoginContent: { padding: 20, paddingBottom: Platform.OS === "ios" ? 50 : 30, flex: 1, }, emailInputContainer: { flexDirection: "row", alignItems: "center", borderWidth: 1, borderColor: "#E1E1E1", borderRadius: 25, height: 50, marginBottom: 20, }, emailInput: { flex: 1, height: "100%", paddingHorizontal: 16, fontSize: 16, paddingRight: 36, }, emailClearButton: { position: "absolute", right: 12, top: "50%", transform: [{ translateY: -12 }], height: 24, width: 24, justifyContent: "center", alignItems: "center", }, emailClearButtonText: { fontSize: 16, color: "#999", fontWeight: "500", textAlign: "center", }, suggestionsContainer: { borderWidth: 1, borderColor: "#E1E1E1", borderRadius: 10, marginTop: -10, marginBottom: 20, maxHeight: 200, backgroundColor: "#fff", }, suggestionsList: { padding: 8, }, suggestionItem: { paddingVertical: 12, paddingHorizontal: 16, borderBottomWidth: 1, borderBottomColor: "#F0F0F0", }, suggestionText: { fontSize: 16, color: "#333", }, passwordContainer: { flexDirection: "row", alignItems: "center", borderWidth: 1, borderColor: "#E1E1E1", borderRadius: 25, height: 50, marginBottom: 20, position: "relative", }, passwordInput: { flex: 1, height: "100%", paddingHorizontal: 16, fontSize: 16, }, passwordErrorContainer: { borderColor: "#FF3B30", }, passwordErrorIcon: { position: "absolute", right: 12, top: "50%", transform: [{ translateY: -12 }], width: 24, height: 24, backgroundColor: "#FF3B30", borderRadius: 12, justifyContent: "center", alignItems: "center", }, passwordErrorIconText: { color: "white", fontWeight: "bold", fontSize: 16, }, passwordErrorText: { color: "#FF3B30", fontSize: 14, marginTop: -12, marginBottom: 16, paddingHorizontal: 5, }, forgotPasswordLink: { alignItems: "center", marginTop: 5, }, forgotPasswordLinkText: { color: "#0066FF", fontSize: 14, }, emailContinueButton: { height: 50, backgroundColor: "#0039CB", borderRadius: 25, justifyContent: "center", alignItems: "center", marginTop: 20, }, emailDisabledButton: { backgroundColor: "#CCCCCC", }, emailContinueButtonText: { color: "#fff", fontSize: 16, fontWeight: "600", }, }); export default EmailLoginModal;