import locationData from '@/assets/json/location.json'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import Modal from 'react-native-modal'; import Cascader, { CascaderItem } from '../cascader'; import { convertRegions } from '../utils/cascaderData'; interface LocationModalProps { modalVisible: boolean; setModalVisible: (visible: boolean) => void; podiumPosition: { x: number, y: number, width: number, height: number }; handleChange: (selectedItems: CascaderItem[]) => void; } const LocationModal = React.memo((props: LocationModalProps) => { const { modalVisible, setModalVisible, podiumPosition, handleChange } = props; const transformed = convertRegions(locationData, { nameKey: 'name', // 源数据中表示"名称"的字段 valueKey: 'name', // 源数据中作为 value 的字段 regionsKey: 'regions', // 源数据中表示"子级区域"的字段 childrenKey: 'children' // 输出结构中表示"子级区域"的字段 }); const { t } = useTranslation(); return ( setModalVisible(false)} swipeDirection="right" // 支持向右滑动关闭 propagateSwipe={true} animationIn="slideInRight" // 入场动画 animationOut="slideOutRight" // 出场动画 backdropOpacity={0.5} onSwipeComplete={() => setModalVisible(false)} style={{ margin: 0, justifyContent: 'flex-start', marginTop: podiumPosition.height + podiumPosition.y }} > Settings {t('generalSetting.location', { ns: 'personal' })} setModalVisible(false)}> × { setModalVisible(false) }} activeOpacity={0.8} > {t('generalSetting.confirm', { ns: 'personal' })} ); }, areEqual); function areEqual(prevProps: LocationModalProps, nextProps: LocationModalProps) { // 只有当这些 props 变化时才重新渲染 return ( prevProps.modalVisible === nextProps.modalVisible && prevProps.podiumPosition.x === nextProps.podiumPosition.x && prevProps.podiumPosition.y === nextProps.podiumPosition.y && prevProps.podiumPosition.width === nextProps.podiumPosition.width && prevProps.podiumPosition.height === nextProps.podiumPosition.height ); } const styles = StyleSheet.create({ modalView: { width: '100%', height: '60%', backgroundColor: 'white', borderRadius: 24, paddingVertical: 16, }, modalHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20, borderBottomWidth: 1, borderBottomColor: '#E5E5E5', }, modalTitle: { fontSize: 20, fontWeight: 'bold', color: '#4C320C', }, closeButton: { fontSize: 28, color: '#4C320C', padding: 10, }, modalContent: { flex: 1, paddingHorizontal: 16, }, 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', }, confirmButton: { backgroundColor: '#E2793F', borderRadius: 20, paddingHorizontal: 16, paddingVertical: 8, marginHorizontal: 16, display: 'flex', justifyContent: 'center', alignItems: 'center', }, }); export default LocationModal;