feat(Theme): enhance theming and UI consistency across components
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 8m15s
Frontend CI / ota-android (push) Successful in 10m56s
Frontend CI / build-android-apk (push) Successful in 1h3m22s

- 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:
lafay
2026-03-25 05:16:54 +08:00
parent 90d834695f
commit 4ee3079b9f
86 changed files with 6777 additions and 5890 deletions

View File

@@ -4,7 +4,7 @@
* 使用 expo-image 实现内存+磁盘双级缓存,头像秒加载
*/
import React from 'react';
import React, { useMemo } from 'react';
import {
View,
TouchableOpacity,
@@ -12,7 +12,7 @@ import {
ViewStyle,
} from 'react-native';
import { Image as ExpoImage } from 'expo-image';
import { colors, borderRadius } from '../../theme';
import { borderRadius, useAppColors, type AppColors } from '../../theme';
import Text from './Text';
type AvatarSource = string | { uri: string } | number | null;
@@ -27,29 +27,50 @@ interface AvatarProps {
style?: ViewStyle;
}
function createAvatarStyles(colors: AppColors) {
return StyleSheet.create({
container: {
position: 'relative',
},
image: {
backgroundColor: colors.background.disabled,
},
placeholder: {
backgroundColor: colors.primary.main,
justifyContent: 'center',
alignItems: 'center',
},
badge: {
position: 'absolute',
borderWidth: 2,
borderColor: colors.background.paper,
},
});
}
const Avatar: React.FC<AvatarProps> = ({
source,
size = 40,
name,
onPress,
showBadge = false,
badgeColor = colors.success.main,
badgeColor,
style,
}) => {
// 获取首字母
const colors = useAppColors();
const styles = useMemo(() => createAvatarStyles(colors), [colors]);
const resolvedBadgeColor = badgeColor ?? colors.success.main;
const getInitial = (): string => {
if (!name) return '?';
const firstChar = name.charAt(0).toUpperCase();
// 中文字符
if (/[\u4e00-\u9fa5]/.test(firstChar)) {
return firstChar;
}
return firstChar;
};
// 渲染头像内容
const renderAvatarContent = () => {
// 如果有图片源
if (source) {
const imageSource =
typeof source === 'string' ? { uri: source } : source;
@@ -72,7 +93,6 @@ const Avatar: React.FC<AvatarProps> = ({
);
}
// 显示首字母
const fontSize = size / 2;
return (
<View
@@ -100,7 +120,7 @@ const Avatar: React.FC<AvatarProps> = ({
style={[
styles.badge,
{
backgroundColor: badgeColor,
backgroundColor: resolvedBadgeColor,
width: size * 0.3,
height: size * 0.3,
borderRadius: (size * 0.3) / 2,
@@ -124,23 +144,4 @@ const Avatar: React.FC<AvatarProps> = ({
return avatarContainer;
};
const styles = StyleSheet.create({
container: {
position: 'relative',
},
image: {
backgroundColor: colors.background.disabled,
},
placeholder: {
backgroundColor: colors.primary.main,
justifyContent: 'center',
alignItems: 'center',
},
badge: {
position: 'absolute',
borderWidth: 2,
borderColor: colors.background.paper,
},
});
export default Avatar;