feat: 同步dev分支并保留当前修改
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
ActivityIndicator,
|
||||
ScrollView,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import { colors, spacing, fontSizes, borderRadius } from '../../theme';
|
||||
import { Text, ResponsiveContainer } from '../../components/common';
|
||||
@@ -17,9 +17,13 @@ import { showPrompt } from '../../services/promptService';
|
||||
import { useAuthStore } from '../../stores';
|
||||
|
||||
export const AccountSecurityScreen: React.FC = () => {
|
||||
const { isWideScreen } = useResponsive();
|
||||
const { isWideScreen, isMobile } = useResponsive();
|
||||
const insets = useSafeAreaInsets();
|
||||
const currentUser = useAuthStore((state) => state.currentUser);
|
||||
const fetchCurrentUser = useAuthStore((state) => state.fetchCurrentUser);
|
||||
|
||||
// 底部间距,避免被 TabBar 遮挡
|
||||
const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.md;
|
||||
|
||||
const [email, setEmail] = useState(currentUser?.email || '');
|
||||
const [verificationCode, setVerificationCode] = useState('');
|
||||
@@ -330,10 +334,10 @@ export const AccountSecurityScreen: React.FC = () => {
|
||||
<SafeAreaView style={styles.container} edges={['bottom']}>
|
||||
{isWideScreen ? (
|
||||
<ResponsiveContainer maxWidth={800}>
|
||||
<ScrollView contentContainerStyle={styles.scrollContent}>{content}</ScrollView>
|
||||
<ScrollView contentContainerStyle={[styles.scrollContent, { paddingBottom: scrollBottomInset }]}>{content}</ScrollView>
|
||||
</ResponsiveContainer>
|
||||
) : (
|
||||
<ScrollView contentContainerStyle={styles.scrollContent}>{content}</ScrollView>
|
||||
<ScrollView contentContainerStyle={[styles.scrollContent, { paddingBottom: scrollBottomInset }]}>{content}</ScrollView>
|
||||
)}
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
View,
|
||||
Alert,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { Avatar, Button, EmptyState, ResponsiveContainer, Text } from '../../components/common';
|
||||
@@ -16,15 +16,21 @@ import { authService } from '../../services';
|
||||
import { colors, spacing, borderRadius, shadows } from '../../theme';
|
||||
import { User } from '../../types';
|
||||
import { RootStackParamList } from '../../navigation/types';
|
||||
import { useResponsive } from '../../hooks';
|
||||
|
||||
type NavigationProp = NativeStackNavigationProp<RootStackParamList>;
|
||||
|
||||
export const BlockedUsersScreen: React.FC = () => {
|
||||
const navigation = useNavigation<NavigationProp>();
|
||||
const { isMobile } = useResponsive();
|
||||
const insets = useSafeAreaInsets();
|
||||
const [users, setUsers] = useState<User[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [processingUserId, setProcessingUserId] = useState<string | null>(null);
|
||||
|
||||
// 底部间距,避免被 TabBar 遮挡
|
||||
const listBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.md;
|
||||
|
||||
const loadBlockedUsers = useCallback(async () => {
|
||||
try {
|
||||
@@ -115,7 +121,7 @@ export const BlockedUsersScreen: React.FC = () => {
|
||||
data={users}
|
||||
keyExtractor={item => item.id}
|
||||
renderItem={renderItem}
|
||||
contentContainerStyle={[styles.listContent, users.length === 0 && styles.emptyContent]}
|
||||
contentContainerStyle={[styles.listContent, users.length === 0 && styles.emptyContent, { paddingBottom: listBottomInset }]}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
|
||||
@@ -102,7 +102,8 @@ export const EditProfileScreen: React.FC = () => {
|
||||
const [uploadingAvatar, setUploadingAvatar] = useState(false);
|
||||
const [uploadingCover, setUploadingCover] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const bottomSafeDistance = isMobile ? insets.bottom + 92 : spacing.xl;
|
||||
// 底部间距,避免被 TabBar 遮挡
|
||||
const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.lg;
|
||||
|
||||
// 根据屏幕宽度计算封面高度
|
||||
const coverHeight = isWideScreen ? Math.min((width * 9) / 16, 300) : (width * 9) / 16;
|
||||
@@ -471,7 +472,7 @@ export const EditProfileScreen: React.FC = () => {
|
||||
</View>
|
||||
|
||||
{/* 保存按钮 */}
|
||||
<View style={[styles.buttonContainer, { marginBottom: bottomSafeDistance }]}>
|
||||
<View style={[styles.buttonContainer, { marginBottom: scrollBottomInset }]}>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.saveButton,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
Switch,
|
||||
ScrollView,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { colors, spacing, fontSizes, borderRadius } from '../../theme';
|
||||
@@ -34,7 +34,11 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
const [vibrationEnabled, setVibrationEnabledState] = useState(true);
|
||||
const [pushEnabled, setPushEnabled] = useState(true);
|
||||
const [soundEnabled, setSoundEnabled] = useState(true);
|
||||
const { isWideScreen } = useResponsive();
|
||||
const { isWideScreen, isMobile } = useResponsive();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
// 底部间距,避免被 TabBar 遮挡
|
||||
const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.md;
|
||||
|
||||
// 加载设置
|
||||
useEffect(() => {
|
||||
@@ -150,12 +154,12 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
<SafeAreaView style={styles.container} edges={['bottom']}>
|
||||
{isWideScreen ? (
|
||||
<ResponsiveContainer maxWidth={800}>
|
||||
<ScrollView contentContainerStyle={styles.scrollContent}>
|
||||
<ScrollView contentContainerStyle={[styles.scrollContent, { paddingBottom: scrollBottomInset }]}>
|
||||
{renderContent()}
|
||||
</ScrollView>
|
||||
</ResponsiveContainer>
|
||||
) : (
|
||||
<ScrollView contentContainerStyle={styles.scrollContent}>
|
||||
<ScrollView contentContainerStyle={[styles.scrollContent, { paddingBottom: scrollBottomInset }]}>
|
||||
{renderContent()}
|
||||
</ScrollView>
|
||||
)}
|
||||
|
||||
@@ -55,10 +55,12 @@ export const ProfileScreen: React.FC = () => {
|
||||
const { isDesktop, isTablet, width } = useResponsive();
|
||||
|
||||
// 页面滚动底部安全间距,避免内容被底部 TabBar 遮挡
|
||||
// TabBar 悬浮:高度 64 + 浮动间距 12*2 = 88
|
||||
const scrollBottomInset = useMemo(() => {
|
||||
if (isDesktop) return spacing.lg;
|
||||
return tabBarHeight + insets.bottom + spacing.md;
|
||||
}, [isDesktop, tabBarHeight, insets.bottom]);
|
||||
const FLOATING_TAB_BAR_HEIGHT = 64 + 24; // TabBar高度 + 上下浮动间距
|
||||
return FLOATING_TAB_BAR_HEIGHT + insets.bottom + spacing.md;
|
||||
}, [isDesktop, insets.bottom]);
|
||||
|
||||
const [activeTab, setActiveTab] = useState(0);
|
||||
const [posts, setPosts] = useState<Post[]>([]);
|
||||
|
||||
@@ -20,6 +20,7 @@ import { colors, spacing, fontSizes, borderRadius } from '../../theme';
|
||||
import { useAuthStore } from '../../stores';
|
||||
import { Text, ResponsiveContainer } from '../../components/common';
|
||||
import { useResponsive } from '../../hooks';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
interface SettingsItem {
|
||||
key: string;
|
||||
@@ -67,6 +68,11 @@ export const SettingsScreen: React.FC = () => {
|
||||
const navigation = useNavigation();
|
||||
const { logout } = useAuthStore();
|
||||
const { isWideScreen } = useResponsive();
|
||||
const insets = useSafeAreaInsets();
|
||||
const { isMobile } = useResponsive();
|
||||
|
||||
// 底部间距,避免被 TabBar 遮挡
|
||||
const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.md;
|
||||
|
||||
// 处理设置项点击
|
||||
const handleItemPress = (key: string) => {
|
||||
@@ -200,12 +206,12 @@ export const SettingsScreen: React.FC = () => {
|
||||
<SafeAreaView style={styles.container} edges={['bottom']}>
|
||||
{isWideScreen ? (
|
||||
<ResponsiveContainer maxWidth={800}>
|
||||
<ScrollView contentContainerStyle={styles.scrollContent}>
|
||||
<ScrollView contentContainerStyle={[styles.scrollContent, { paddingBottom: scrollBottomInset }]}>
|
||||
{renderContent()}
|
||||
</ScrollView>
|
||||
</ResponsiveContainer>
|
||||
) : (
|
||||
<ScrollView contentContainerStyle={styles.scrollContent}>
|
||||
<ScrollView contentContainerStyle={[styles.scrollContent, { paddingBottom: scrollBottomInset }]}>
|
||||
{renderContent()}
|
||||
</ScrollView>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user