feat(chat): enhance chat settings and message bubble styles
All checks were successful
Frontend CI / ota-android (push) Successful in 12m37s
Frontend CI / build-and-push-web (push) Successful in 22m42s
Frontend CI / build-android-apk (push) Successful in 57m42s

- Introduced dynamic chat settings for font size and message bubble radius, improving user customization.
- Updated ChatScreen styles to support dynamic themes and responsive layouts.
- Refactored bubble styles to utilize dynamic properties for better visual consistency.
- Simplified chat settings management by integrating Zustand store for state management.

This update significantly enhances the chat interface and user experience by allowing personalized settings and improved visual elements.
This commit is contained in:
lafay
2026-04-01 16:30:44 +08:00
parent c771bd9755
commit 72842352d9
14 changed files with 507 additions and 109 deletions

View File

@@ -1,11 +1,12 @@
/**
* ChatScreen 样式定义
* 支持响应式布局
* 支持响应式布局和动态聊天设置
*/
import { useMemo } from 'react';
import { StyleSheet, Dimensions } from 'react-native';
import { spacing, shadows, useAppColors, type AppColors } from '../../../../theme';
import { useChatSettingsStore, CHAT_THEMES } from '../../../../stores/chatSettingsStore';
const { width: SCREEN_WIDTH } = Dimensions.get('window');
@@ -19,17 +20,66 @@ const BREAKPOINTS = {
const isWideScreen = SCREEN_WIDTH >= BREAKPOINTS.desktop;
const isTablet = SCREEN_WIDTH >= BREAKPOINTS.tablet;
export function createChatScreenStyles(colors: AppColors) {
// Hook 获取动态样式参数
export function useChatDynamicStyles() {
const fontSize = useChatSettingsStore((s) => s.fontSize);
const messageRadius = useChatSettingsStore((s) => s.messageRadius);
const themeIndex = useChatSettingsStore((s) => s.themeIndex);
const theme = CHAT_THEMES[themeIndex];
return {
fontSize,
messageRadius,
// 气泡颜色
outgoingBubbleColor: theme.bubble,
// 背景色
chatBackgroundColor: theme.secondary,
// 卡片/头部背景色
cardBackgroundColor: theme.card,
// 输入框背景色
inputBackgroundColor: theme.inputBg,
// 面板背景色
panelBackgroundColor: theme.panelBg,
// 主要文字颜色
textPrimaryColor: theme.textPrimary,
// 次要文字颜色
textSecondaryColor: theme.textSecondary,
};
}
export function createChatScreenStyles(colors: AppColors, dynamicStyles?: {
fontSize?: number;
messageRadius?: number;
outgoingBubbleColor?: string;
chatBackgroundColor?: string;
cardBackgroundColor?: string;
inputBackgroundColor?: string;
panelBackgroundColor?: string;
textPrimaryColor?: string;
textSecondaryColor?: string;
}) {
const fontSize = dynamicStyles?.fontSize ?? 16;
const messageRadius = dynamicStyles?.messageRadius ?? 12;
// 主题颜色(优先使用主题色,否则使用默认色)
const myBubbleBg = dynamicStyles?.outgoingBubbleColor || colors.chat.bubbleOutgoing;
const screenBgColor = dynamicStyles?.chatBackgroundColor || colors.chat.screen;
const cardBgColor = dynamicStyles?.cardBackgroundColor || colors.chat.card;
const inputBgColor = dynamicStyles?.inputBackgroundColor || colors.chat.surfaceRaised;
const panelBgColor = dynamicStyles?.panelBackgroundColor || colors.chat.surfaceMuted;
const textPrimary = dynamicStyles?.textPrimaryColor || colors.chat.textPrimary;
const textSecondary = dynamicStyles?.textSecondaryColor || colors.chat.textSecondary;
return StyleSheet.create({
// 容器
container: {
flex: 1,
backgroundColor: colors.chat.screen,
backgroundColor: screenBgColor,
},
// 头部
headerContainer: {
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: colors.chat.border,
},
@@ -39,7 +89,7 @@ export function createChatScreenStyles(colors: AppColors) {
justifyContent: 'space-between',
paddingHorizontal: spacing.md,
paddingVertical: spacing.sm + 2,
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
height: 56,
},
backButton: {
@@ -69,7 +119,7 @@ export function createChatScreenStyles(colors: AppColors) {
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
overflow: 'hidden',
},
groupAvatar: {
@@ -91,13 +141,13 @@ export function createChatScreenStyles(colors: AppColors) {
},
headerName: {
fontWeight: '600',
color: colors.text.primary,
color: textPrimary,
fontSize: 16,
letterSpacing: -0.3,
},
memberCount: {
fontSize: 12,
color: colors.text.secondary,
color: textSecondary,
fontWeight: '400',
},
typingHint: {
@@ -241,9 +291,9 @@ export function createChatScreenStyles(colors: AppColors) {
fontWeight: '600',
},
// 消息气泡 - 微信风格:更小的圆角 + 更紧凑的内边距
// 消息气泡 - 动态圆角支持
messageBubbleOuter: {
borderRadius: 12,
borderRadius: messageRadius,
minWidth: 44,
shadowColor: colors.chat.shadow,
shadowOffset: { width: 0, height: 1 },
@@ -252,44 +302,44 @@ export function createChatScreenStyles(colors: AppColors) {
elevation: 1,
},
myBubbleOuter: {
borderBottomRightRadius: 4, // 微信的小尾巴更尖
borderBottomRightRadius: Math.max(4, messageRadius * 0.3), // 微信的小尾巴更尖
},
theirBubbleOuter: {
borderTopLeftRadius: 4,
borderTopLeftRadius: Math.max(4, messageRadius * 0.3),
},
// 内层:更紧凑的微信风格内边距
// 内层:动态圆角支持
messageBubbleInner: {
borderRadius: 12,
borderRadius: messageRadius,
overflow: 'hidden',
paddingHorizontal: 10, // 微信:更窄的左右边距
paddingVertical: 7, // 微信:更紧的上下边距
minWidth: 44,
},
myBubbleInner: {
backgroundColor: colors.chat.bubbleOutgoing,
borderBottomRightRadius: 4,
backgroundColor: myBubbleBg,
borderBottomRightRadius: Math.max(4, messageRadius * 0.3),
},
theirBubbleInner: {
backgroundColor: colors.chat.bubbleIncoming,
borderTopLeftRadius: 4,
backgroundColor: cardBgColor,
borderTopLeftRadius: Math.max(4, messageRadius * 0.3),
},
recalledBubble: {
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
borderWidth: 1,
borderColor: colors.chat.border,
borderStyle: 'dashed',
},
myBubbleText: {
color: colors.chat.textPrimary, // 使用主题文字颜色
fontSize: 18,
lineHeight: 25,
color: textPrimary, // 使用主题文字颜色
fontSize,
lineHeight: Math.round(fontSize * 1.4),
letterSpacing: 0.1,
fontWeight: '400',
},
theirBubbleText: {
color: colors.chat.textPrimary, // 使用主题文字颜色
fontSize: 18,
lineHeight: 25,
color: textPrimary, // 使用主题文字颜色
fontSize,
lineHeight: Math.round(fontSize * 1.4),
letterSpacing: 0.1,
fontWeight: '400',
},
@@ -362,7 +412,7 @@ export function createChatScreenStyles(colors: AppColors) {
// 输入框区域 - 与列表背景同色底栏,顶部细分隔
inputWrapper: {
backgroundColor: colors.chat.screen,
backgroundColor: screenBgColor,
borderTopWidth: StyleSheet.hairlineWidth,
borderTopColor: 'rgba(0, 0, 0, 0.06)',
},
@@ -384,7 +434,7 @@ export function createChatScreenStyles(colors: AppColors) {
inputInner: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: colors.chat.surfaceRaised,
backgroundColor: inputBgColor,
borderRadius: 20,
paddingHorizontal: spacing.xs,
paddingVertical: 4,
@@ -518,7 +568,7 @@ export function createChatScreenStyles(colors: AppColors) {
// 面板
panelWrapper: {
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
borderTopWidth: 1,
borderTopColor: colors.chat.border,
shadowColor: colors.chat.shadow,
@@ -529,11 +579,11 @@ export function createChatScreenStyles(colors: AppColors) {
},
// 表情面板包装器 - 底部 tab 栏是白色,安全区域也用白色填充
emojiPanelWrapper: {
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
},
panelContainer: {
flex: 1,
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
},
// 表情面板
@@ -578,12 +628,12 @@ export function createChatScreenStyles(colors: AppColors) {
paddingVertical: spacing.sm + 2,
borderTopWidth: StyleSheet.hairlineWidth,
borderTopColor: colors.chat.borderHairline,
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
},
panelTabContainer: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
borderRadius: 12,
padding: 3,
},
@@ -595,7 +645,7 @@ export function createChatScreenStyles(colors: AppColors) {
borderRadius: 10,
},
panelTabActive: {
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
shadowColor: colors.chat.shadow,
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.08,
@@ -617,7 +667,7 @@ export function createChatScreenStyles(colors: AppColors) {
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
},
// 自定义表情面板
@@ -656,7 +706,7 @@ export function createChatScreenStyles(colors: AppColors) {
margin: 4,
borderRadius: 8,
overflow: 'hidden',
backgroundColor: colors.chat.surfaceInput,
backgroundColor: inputBgColor,
},
stickerImage: {
width: '100%',
@@ -684,7 +734,7 @@ export function createChatScreenStyles(colors: AppColors) {
alignItems: 'center',
justifyContent: 'center',
marginBottom: spacing.sm + 2,
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
shadowColor: colors.chat.shadow,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.06,
@@ -709,14 +759,14 @@ export function createChatScreenStyles(colors: AppColors) {
},
moreItemText: {
fontSize: 12,
color: colors.chat.textSecondary,
color: textSecondary,
fontWeight: '500',
letterSpacing: 0.3,
},
// MorePanel 整体背景
morePanelBackground: {
flex: 1,
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
},
// @成员选择浮层 - 绝对定位浮在输入框上方
@@ -724,7 +774,7 @@ export function createChatScreenStyles(colors: AppColors) {
position: 'absolute',
left: 12,
right: 12,
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderRadius: 18,
shadowColor: colors.primary.main,
shadowOffset: { width: 0, height: -3 },
@@ -739,7 +789,7 @@ export function createChatScreenStyles(colors: AppColors) {
// @成员选择面板
mentionPanelContainer: {
flex: 1,
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderRadius: 18,
},
mentionPanelDragHandle: {
@@ -774,7 +824,7 @@ export function createChatScreenStyles(colors: AppColors) {
width: 26,
height: 26,
borderRadius: 13,
backgroundColor: colors.chat.surfaceInput,
backgroundColor: inputBgColor,
alignItems: 'center',
justifyContent: 'center',
},
@@ -851,7 +901,7 @@ export function createChatScreenStyles(colors: AppColors) {
},
// 旧版菜单样式(保留兼容)
menuContainer: {
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderRadius: 12,
minWidth: 160,
shadowColor: colors.chat.shadow,
@@ -873,12 +923,12 @@ export function createChatScreenStyles(colors: AppColors) {
},
menuItemText: {
fontSize: 15,
color: colors.text.primary,
color: textPrimary,
fontWeight: '500',
},
// 底部菜单容器
bottomMenuContainer: {
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
paddingTop: spacing.md,
@@ -891,7 +941,7 @@ export function createChatScreenStyles(colors: AppColors) {
},
// 消息预览区域
messagePreviewContainer: {
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
marginHorizontal: spacing.md,
marginBottom: spacing.md,
paddingHorizontal: spacing.md,
@@ -934,12 +984,12 @@ export function createChatScreenStyles(colors: AppColors) {
},
menuActionLabel: {
fontSize: 13,
color: colors.text.primary,
color: textPrimary,
fontWeight: '500',
},
// 取消按钮
menuCancelButton: {
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
marginHorizontal: spacing.md,
paddingVertical: spacing.md,
borderRadius: 12,
@@ -947,7 +997,7 @@ export function createChatScreenStyles(colors: AppColors) {
},
menuCancelText: {
fontSize: 16,
color: colors.text.primary,
color: textPrimary,
fontWeight: '600',
},
@@ -1037,7 +1087,7 @@ export function createChatScreenStyles(colors: AppColors) {
zIndex: 1000,
},
overlayContent: {
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
padding: spacing.xl,
borderRadius: 16,
alignItems: 'center',
@@ -1056,7 +1106,7 @@ export function createChatScreenStyles(colors: AppColors) {
// 表情包添加按钮(管理界面第一位)
stickerAddButton: {
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderWidth: 1.5,
borderColor: colors.primary.main,
borderStyle: 'dashed',
@@ -1075,7 +1125,7 @@ export function createChatScreenStyles(colors: AppColors) {
// 表情包管理按钮(表情面板第一位)
stickerManageButton: {
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderWidth: 1,
borderColor: colors.chat.border,
borderStyle: 'dashed',
@@ -1146,7 +1196,7 @@ export function createChatScreenStyles(colors: AppColors) {
// 表情管理模态框
manageModalContainer: {
backgroundColor: colors.chat.surfaceMuted,
backgroundColor: panelBgColor,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
overflow: 'hidden',
@@ -1157,7 +1207,7 @@ export function createChatScreenStyles(colors: AppColors) {
justifyContent: 'space-between',
paddingHorizontal: spacing.md,
paddingVertical: spacing.md,
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderBottomWidth: 1,
borderBottomColor: colors.chat.border,
},
@@ -1183,7 +1233,7 @@ export function createChatScreenStyles(colors: AppColors) {
manageInfoBar: {
paddingHorizontal: spacing.md,
paddingVertical: spacing.sm,
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderBottomWidth: 1,
borderBottomColor: colors.chat.border,
},
@@ -1204,7 +1254,7 @@ export function createChatScreenStyles(colors: AppColors) {
justifyContent: 'space-between',
paddingHorizontal: spacing.md,
paddingVertical: spacing.md,
backgroundColor: colors.chat.card,
backgroundColor: cardBgColor,
borderTopWidth: 1,
borderTopColor: colors.chat.border,
paddingBottom: 34, // 安全区域
@@ -1279,5 +1329,6 @@ export function createChatScreenStyles(colors: AppColors) {
export function useChatScreenStyles() {
const colors = useAppColors();
return useMemo(() => createChatScreenStyles(colors), [colors]);
const dynamicStyles = useChatDynamicStyles();
return useMemo(() => createChatScreenStyles(colors, dynamicStyles), [colors, dynamicStyles]);
}