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:
@@ -3,10 +3,10 @@
|
||||
* onPress 引用不参与比较,请配合父组件 ref + 按 id 查最新会话使用。
|
||||
*/
|
||||
|
||||
import React, { memo, useEffect, useRef, useState } from 'react';
|
||||
import React, { memo, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Animated, StyleSheet, TouchableOpacity, View } from 'react-native';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import { colors, spacing, shadows } from '../../../theme';
|
||||
import { spacing, shadows, useAppColors, type AppColors } from '../../../theme';
|
||||
import {
|
||||
ConversationResponse,
|
||||
extractTextFromSegments,
|
||||
@@ -150,6 +150,124 @@ function areConversationRowEqual(
|
||||
return true;
|
||||
}
|
||||
|
||||
function createConversationRowStyles(colors: AppColors) {
|
||||
return StyleSheet.create({
|
||||
conversationItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: spacing.md,
|
||||
paddingVertical: 14,
|
||||
backgroundColor: colors.background.paper,
|
||||
marginHorizontal: spacing.md,
|
||||
marginTop: spacing.sm,
|
||||
borderRadius: 12,
|
||||
...shadows.sm,
|
||||
},
|
||||
conversationItemSelected: {
|
||||
backgroundColor: colors.primary.light + '20',
|
||||
borderColor: colors.primary.main,
|
||||
borderWidth: 1,
|
||||
},
|
||||
avatarContainer: {
|
||||
position: 'relative',
|
||||
},
|
||||
systemAvatar: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: colors.primary.main,
|
||||
},
|
||||
conversationContent: {
|
||||
flex: 1,
|
||||
marginLeft: spacing.md,
|
||||
},
|
||||
conversationHeader: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 4,
|
||||
},
|
||||
nameRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
officialBadge: {
|
||||
backgroundColor: colors.primary.main,
|
||||
borderRadius: 4,
|
||||
paddingHorizontal: 6,
|
||||
paddingVertical: 2,
|
||||
marginRight: spacing.xs,
|
||||
},
|
||||
officialBadgeText: {
|
||||
color: colors.primary.contrast,
|
||||
fontSize: 10,
|
||||
fontWeight: '600',
|
||||
},
|
||||
userName: {
|
||||
fontWeight: '600',
|
||||
color: colors.text.primary,
|
||||
fontSize: 16,
|
||||
},
|
||||
groupIcon: {
|
||||
marginRight: 4,
|
||||
},
|
||||
memberCount: {
|
||||
fontSize: 12,
|
||||
color: colors.text.secondary,
|
||||
marginLeft: 2,
|
||||
},
|
||||
pinnedIcon: {
|
||||
marginLeft: 6,
|
||||
},
|
||||
groupAvatar: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
},
|
||||
groupAvatarPlaceholder: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
borderRadius: 12,
|
||||
backgroundColor: colors.primary.main,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
timeText: {
|
||||
color: colors.text.secondary,
|
||||
fontSize: 12,
|
||||
},
|
||||
messageRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
messageText: {
|
||||
flex: 1,
|
||||
color: colors.text.secondary,
|
||||
fontSize: 14,
|
||||
},
|
||||
unreadMessageText: {
|
||||
color: colors.text.primary,
|
||||
fontWeight: '500',
|
||||
},
|
||||
unreadBadge: {
|
||||
minWidth: 20,
|
||||
height: 20,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.primary.main,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginLeft: spacing.sm,
|
||||
paddingHorizontal: 6,
|
||||
},
|
||||
unreadBadgeText: {
|
||||
color: colors.primary.contrast,
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const ConversationListRowInner: React.FC<ConversationListRowProps> = ({
|
||||
item,
|
||||
scale,
|
||||
@@ -158,6 +276,8 @@ const ConversationListRowInner: React.FC<ConversationListRowProps> = ({
|
||||
formatTime,
|
||||
systemChannelId,
|
||||
}) => {
|
||||
const colors = useAppColors();
|
||||
const styles = useMemo(() => createConversationRowStyles(colors), [colors]);
|
||||
const isSystemChannel = item.id === systemChannelId;
|
||||
const isGroupChat = !!(item.type === 'group' && item.group);
|
||||
|
||||
@@ -196,7 +316,7 @@ const ConversationListRowInner: React.FC<ConversationListRowProps> = ({
|
||||
<View style={styles.avatarContainer}>
|
||||
{isSystemChannel ? (
|
||||
<View style={styles.systemAvatar}>
|
||||
<MaterialCommunityIcons name="bell-ring" size={24} color="#FFF" />
|
||||
<MaterialCommunityIcons name="bell-ring" size={24} color={colors.primary.contrast} />
|
||||
</View>
|
||||
) : isGroupChat ? (
|
||||
<View style={styles.groupAvatar}>
|
||||
@@ -204,7 +324,7 @@ const ConversationListRowInner: React.FC<ConversationListRowProps> = ({
|
||||
<Avatar source={displayAvatar} size={50} name={displayName} />
|
||||
) : (
|
||||
<View style={styles.groupAvatarPlaceholder}>
|
||||
<MaterialCommunityIcons name="account-group" size={28} color="#FFF" />
|
||||
<MaterialCommunityIcons name="account-group" size={28} color={colors.primary.contrast} />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
@@ -271,119 +391,3 @@ const ConversationListRowInner: React.FC<ConversationListRowProps> = ({
|
||||
ConversationListRowInner.displayName = 'ConversationListRow';
|
||||
|
||||
export const ConversationListRow = memo(ConversationListRowInner, areConversationRowEqual);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
conversationItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: spacing.md,
|
||||
paddingVertical: 14,
|
||||
backgroundColor: '#FFF',
|
||||
marginHorizontal: spacing.md,
|
||||
marginTop: spacing.sm,
|
||||
borderRadius: 12,
|
||||
...shadows.sm,
|
||||
},
|
||||
conversationItemSelected: {
|
||||
backgroundColor: colors.primary.light + '20',
|
||||
borderColor: colors.primary.main,
|
||||
borderWidth: 1,
|
||||
},
|
||||
avatarContainer: {
|
||||
position: 'relative',
|
||||
},
|
||||
systemAvatar: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: colors.primary.main,
|
||||
},
|
||||
conversationContent: {
|
||||
flex: 1,
|
||||
marginLeft: spacing.md,
|
||||
},
|
||||
conversationHeader: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 4,
|
||||
},
|
||||
nameRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
officialBadge: {
|
||||
backgroundColor: colors.primary.main,
|
||||
borderRadius: 4,
|
||||
paddingHorizontal: 6,
|
||||
paddingVertical: 2,
|
||||
marginRight: spacing.xs,
|
||||
},
|
||||
officialBadgeText: {
|
||||
color: '#FFF',
|
||||
fontSize: 10,
|
||||
fontWeight: '600',
|
||||
},
|
||||
userName: {
|
||||
fontWeight: '600',
|
||||
color: '#333',
|
||||
fontSize: 16,
|
||||
},
|
||||
groupIcon: {
|
||||
marginRight: 4,
|
||||
},
|
||||
memberCount: {
|
||||
fontSize: 12,
|
||||
color: '#999',
|
||||
marginLeft: 2,
|
||||
},
|
||||
pinnedIcon: {
|
||||
marginLeft: 6,
|
||||
},
|
||||
groupAvatar: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
},
|
||||
groupAvatarPlaceholder: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
borderRadius: 12,
|
||||
backgroundColor: colors.primary.main,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
timeText: {
|
||||
color: '#999',
|
||||
fontSize: 12,
|
||||
},
|
||||
messageRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
messageText: {
|
||||
flex: 1,
|
||||
color: '#888',
|
||||
fontSize: 14,
|
||||
},
|
||||
unreadMessageText: {
|
||||
color: '#333',
|
||||
fontWeight: '500',
|
||||
},
|
||||
unreadBadge: {
|
||||
minWidth: 20,
|
||||
height: 20,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.primary.main,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginLeft: spacing.sm,
|
||||
paddingHorizontal: 6,
|
||||
},
|
||||
unreadBadgeText: {
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user