feat(Theme): enhance theming and UI consistency across components
- Updated app.json to set userInterfaceStyle to automatic for improved theme adaptability. - Refactored layout components to utilize useAppColors for dynamic theming, ensuring consistent color usage. - Introduced SystemChrome component to manage system UI background color based on theme. - Enhanced TabsLayout, ProfileStackLayout, and other components to leverage new theming structure. - Improved QRCodeScanner, SearchBar, and CommentItem styles to align with the updated theme system. - Consolidated styles in SystemMessageItem and TabBar for better maintainability and visual coherence.
This commit is contained in:
@@ -24,7 +24,7 @@ import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
import { useRouter, useFocusEffect } from 'expo-router';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
||||
import { colors, spacing, borderRadius, shadows } from '../../theme';
|
||||
import { useAppColors, useResolvedColorScheme, spacing, borderRadius, shadows, type AppColors } from '../../theme';
|
||||
import { Post } from '../../types';
|
||||
import { useUserStore, useHomeTabBarVisibilityStore } from '../../stores';
|
||||
import { useCurrentUser } from '../../stores/authStore';
|
||||
@@ -56,12 +56,125 @@ type ViewMode = 'list' | 'grid';
|
||||
type PostType = 'follow' | 'hot' | 'latest';
|
||||
type LatestCapsule = { id: string; name: string };
|
||||
|
||||
function createHomeStyles(colors: AppColors) {
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.background.default,
|
||||
},
|
||||
header: {
|
||||
backgroundColor: colors.background.paper,
|
||||
},
|
||||
searchWrapper: {
|
||||
paddingTop: spacing.lg,
|
||||
paddingBottom: spacing.sm,
|
||||
shadowColor: 'transparent',
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: 0,
|
||||
shadowRadius: 0,
|
||||
elevation: 0,
|
||||
},
|
||||
homeTabBar: {
|
||||
marginTop: spacing.xs,
|
||||
marginBottom: spacing.sm,
|
||||
},
|
||||
viewToggleBtn: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
capsuleWrapper: {
|
||||
paddingBottom: spacing.sm,
|
||||
backgroundColor: colors.background.paper,
|
||||
},
|
||||
capsuleList: {
|
||||
gap: spacing.xs,
|
||||
paddingRight: spacing.lg,
|
||||
},
|
||||
capsuleItem: {
|
||||
paddingHorizontal: spacing.md,
|
||||
paddingVertical: spacing.xs,
|
||||
borderRadius: 999,
|
||||
},
|
||||
capsuleText: {
|
||||
fontSize: 13,
|
||||
fontWeight: '600',
|
||||
color: colors.text.secondary,
|
||||
},
|
||||
capsuleTextActive: {
|
||||
color: colors.primary.main,
|
||||
},
|
||||
listContent: {
|
||||
flexGrow: 1,
|
||||
},
|
||||
listHeader: {
|
||||
width: '100%',
|
||||
},
|
||||
contentContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
listItem: {},
|
||||
waterfallScroll: {
|
||||
flex: 1,
|
||||
},
|
||||
waterfallContainer: {
|
||||
width: '100%',
|
||||
flexGrow: 1,
|
||||
},
|
||||
waterfallColumnsRow: {
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
waterfallColumn: {
|
||||
flex: 1,
|
||||
},
|
||||
waterfallItem: {},
|
||||
floatingButton: {
|
||||
position: 'absolute',
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
width: 56,
|
||||
height: 56,
|
||||
borderRadius: 28,
|
||||
backgroundColor: colors.primary.main,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
...shadows.lg,
|
||||
},
|
||||
floatingButtonDesktop: {
|
||||
right: 40,
|
||||
bottom: 40,
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
},
|
||||
floatingButtonWide: {
|
||||
right: 60,
|
||||
bottom: 60,
|
||||
width: 72,
|
||||
height: 72,
|
||||
borderRadius: 36,
|
||||
},
|
||||
loadingMoreFooter: {
|
||||
paddingVertical: 20,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const HomeScreen: React.FC = () => {
|
||||
const router = useRouter();
|
||||
const insets = useSafeAreaInsets();
|
||||
const { posts: storePosts } = useUserStore();
|
||||
const currentUser = useCurrentUser();
|
||||
|
||||
const colors = useAppColors();
|
||||
const resolvedScheme = useResolvedColorScheme();
|
||||
const styles = useMemo(() => createHomeStyles(colors), [colors]);
|
||||
const statusBarStyle = resolvedScheme === 'dark' ? 'light-content' : 'dark-content';
|
||||
|
||||
// 使用响应式 hook
|
||||
const {
|
||||
width,
|
||||
@@ -827,7 +940,7 @@ export const HomeScreen: React.FC = () => {
|
||||
if (showSearch) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={['top', 'bottom']}>
|
||||
<StatusBar barStyle="dark-content" backgroundColor={colors.background.paper} />
|
||||
<StatusBar barStyle={statusBarStyle} backgroundColor={colors.background.paper} />
|
||||
<SearchScreen
|
||||
onBack={() => setShowSearch(false)}
|
||||
/>
|
||||
@@ -838,8 +951,8 @@ export const HomeScreen: React.FC = () => {
|
||||
// 正常首页内容
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={['top', 'bottom']}>
|
||||
<StatusBar barStyle="dark-content" backgroundColor={colors.background.paper} />
|
||||
|
||||
<StatusBar barStyle={statusBarStyle} backgroundColor={colors.background.paper} />
|
||||
|
||||
{/* 顶部Header */}
|
||||
<View style={styles.header}>
|
||||
{/* 搜索栏 */}
|
||||
@@ -942,115 +1055,3 @@ export const HomeScreen: React.FC = () => {
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.background.default,
|
||||
},
|
||||
header: {
|
||||
backgroundColor: colors.background.paper,
|
||||
},
|
||||
searchWrapper: {
|
||||
paddingTop: spacing.lg,
|
||||
paddingBottom: spacing.xs,
|
||||
// 移除阴影效果
|
||||
shadowColor: 'transparent',
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: 0,
|
||||
shadowRadius: 0,
|
||||
elevation: 0,
|
||||
},
|
||||
homeTabBar: {
|
||||
marginTop: 0,
|
||||
marginBottom: spacing.sm,
|
||||
},
|
||||
viewToggleBtn: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
capsuleWrapper: {
|
||||
paddingBottom: spacing.sm,
|
||||
backgroundColor: colors.background.paper,
|
||||
},
|
||||
capsuleList: {
|
||||
gap: spacing.xs,
|
||||
paddingRight: spacing.lg,
|
||||
},
|
||||
capsuleItem: {
|
||||
paddingHorizontal: spacing.md,
|
||||
paddingVertical: spacing.xs,
|
||||
borderRadius: 999,
|
||||
},
|
||||
capsuleText: {
|
||||
fontSize: 13,
|
||||
fontWeight: '600',
|
||||
color: colors.text.secondary,
|
||||
},
|
||||
capsuleTextActive: {
|
||||
color: colors.primary.main,
|
||||
},
|
||||
listContent: {
|
||||
flexGrow: 1,
|
||||
},
|
||||
listHeader: {
|
||||
width: '100%',
|
||||
},
|
||||
contentContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
listItem: {
|
||||
// 动态设置 marginBottom
|
||||
},
|
||||
waterfallScroll: {
|
||||
flex: 1,
|
||||
},
|
||||
waterfallContainer: {
|
||||
width: '100%',
|
||||
flexGrow: 1,
|
||||
},
|
||||
waterfallColumnsRow: {
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
waterfallColumn: {
|
||||
flex: 1,
|
||||
},
|
||||
waterfallItem: {
|
||||
// 动态设置 marginBottom
|
||||
},
|
||||
floatingButton: {
|
||||
position: 'absolute',
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
width: 56,
|
||||
height: 56,
|
||||
borderRadius: 28,
|
||||
backgroundColor: colors.primary.main,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
...shadows.lg,
|
||||
},
|
||||
floatingButtonDesktop: {
|
||||
right: 40,
|
||||
bottom: 40,
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
},
|
||||
floatingButtonWide: {
|
||||
right: 60,
|
||||
bottom: 60,
|
||||
width: 72,
|
||||
height: 72,
|
||||
borderRadius: 36,
|
||||
},
|
||||
loadingMoreFooter: {
|
||||
paddingVertical: 20,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user