refactor(message): improve message synchronization and hook reliability
Some checks failed
Frontend CI / ota-android (push) Successful in 1m29s
Frontend CI / build-and-push-web (push) Failing after 1m31s
Frontend CI / ota-ios (push) Successful in 4m4s
Frontend CI / build-android-apk (push) Successful in 29m5s

Refactor the message management system to address synchronization issues and improve performance through request deduplication and enhanced lifecycle management.

- Implement in-flight promise tracking in `MessageSyncService` to prevent redundant network requests for conversations and messages.
- Enhance `useMessages` hook with `useFocusEffect` to trigger automatic synchronization when a chat screen regains focus.
- Add `forceSync` capability to `MessageManager` and `MessageSyncService` to allow manual overrides of loading states during re-entry.
- Consolidate WebSocket synchronization logic in `WSMessageHandler` using a throttled and deduplicated trigger mechanism.
- Clean up unused styles and deprecated hooks (`baseHooks.ts`, `bubbleStyles.ts`, `inputStyles.ts`).
- Update `metro.config.js` and `package.json` to include `@expo/ui` and optimize resolver settings.
This commit is contained in:
2026-06-03 10:31:46 +08:00
parent 2e6912dddf
commit 2e2f6e3467
13 changed files with 396 additions and 1115 deletions

View File

@@ -1,4 +1,4 @@
/**
/**
* 聊天设置页 ChatSettingsScreen
* 威友 - 聊天个性化设置
*/
@@ -9,7 +9,6 @@ import {
StyleSheet,
TouchableOpacity,
ScrollView,
Dimensions,
PanResponder,
} from 'react-native';
import { StatusBar } from 'expo-status-bar';
@@ -30,7 +29,6 @@ import {
CHAT_THEMES,
} from '../../stores/settings';
const { width: SCREEN_WIDTH } = Dimensions.get('window');
const CARD_MAX_WIDTH = 720;
interface SliderProps {
@@ -43,7 +41,6 @@ interface SliderProps {
showValue?: boolean;
}
// 自定义滑块组件(支持拖动)
const Slider: React.FC<SliderProps> = ({
value,
min,
@@ -56,13 +53,13 @@ const Slider: React.FC<SliderProps> = ({
const colors = useAppColors();
const styles = useMemo(() => createSliderStyles(colors), [colors]);
const trackWidthRef = useRef(0);
const percentage = isNaN(value) ? 0 : ((value - min) / (max - min)) * 100;
const updateValue = useCallback((locationX: number) => {
const width = trackWidthRef.current;
if (width <= 0) return;
const newPercentage = Math.max(0, Math.min(100, (locationX / width) * 100));
const newValue = Math.round(min + (newPercentage / 100) * (max - min));
onValueChange(newValue);
@@ -90,7 +87,7 @@ const Slider: React.FC<SliderProps> = ({
{showValue && <Text style={styles.value}>{isNaN(value) ? 0 : value}</Text>}
{rightLabel && <Text style={styles.label}>{rightLabel}</Text>}
</View>
<View
<View
style={styles.trackContainer}
onLayout={handleLayout}
{...panResponder.panHandlers}
@@ -177,7 +174,6 @@ function createStyles(colors: AppColors) {
textTransform: 'uppercase',
letterSpacing: 0.5,
},
// 聊天预览样式
previewContainer: {
backgroundColor: colors.primary.light + '20',
borderRadius: 14,
@@ -211,7 +207,6 @@ function createStyles(colors: AppColors) {
previewText: {
color: colors.text.primary,
},
// 主题选择样式
themeList: {
flexDirection: 'row',
gap: spacing.sm,
@@ -254,12 +249,6 @@ function createStyles(colors: AppColors) {
justifyContent: 'center',
alignItems: 'center',
},
themeName: {
fontSize: fontSizes.xs,
textAlign: 'center',
marginTop: 4,
color: colors.text.secondary,
},
sliderContainer: {
paddingVertical: 8,
},
@@ -272,7 +261,6 @@ export const ChatSettingsScreen: React.FC = () => {
const styles = useMemo(() => createStyles(colors), [colors]);
const responsivePadding = useResponsiveSpacing({ xs: 8, sm: 12, md: 16, lg: 24, xl: 32 });
// 从 store 获取状态
const fontSize = useChatSettingsStore((s) => s.fontSize);
const messageRadius = useChatSettingsStore((s) => s.messageRadius);
const themeIndex = useChatSettingsStore((s) => s.themeIndex);
@@ -281,14 +269,13 @@ export const ChatSettingsScreen: React.FC = () => {
const currentTheme = CHAT_THEMES[themeIndex];
// 渲染聊天预览
const renderChatPreview = () => (
<View style={styles.section}>
<Text style={styles.sectionTitle}></Text>
<View style={[styles.previewContainer, { backgroundColor: currentTheme.secondary }]}>
<View style={[
styles.previewMessage,
{
styles.previewMessage,
{
borderRadius: messageRadius,
borderTopLeftRadius: Math.max(4, messageRadius * 0.3),
}
@@ -301,11 +288,11 @@ export const ChatSettingsScreen: React.FC = () => {
</Text>
</View>
<View style={[
styles.previewReply,
{
styles.previewReply,
{
borderRadius: messageRadius,
borderBottomRightRadius: Math.max(4, messageRadius * 0.3),
backgroundColor: currentTheme.bubble
backgroundColor: currentTheme.bubble
}
]}>
<Text style={[styles.previewText, { fontSize }]}>
@@ -316,7 +303,6 @@ export const ChatSettingsScreen: React.FC = () => {
</View>
);
// 渲染字号滑块
const renderFontSizeSlider = () => (
<View style={styles.section}>
<Text style={styles.sectionTitle}></Text>
@@ -333,12 +319,11 @@ export const ChatSettingsScreen: React.FC = () => {
</View>
);
// 渲染主题颜色选择
const renderThemeColors = () => (
<View style={styles.section}>
<Text style={styles.sectionTitle}></Text>
<ScrollView
horizontal
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.themeList}
>
@@ -366,7 +351,6 @@ export const ChatSettingsScreen: React.FC = () => {
</View>
);
// 渲染圆角滑块
const renderRadiusSlider = () => (
<View style={styles.section}>
<Text style={styles.sectionTitle}></Text>
@@ -385,9 +369,9 @@ export const ChatSettingsScreen: React.FC = () => {
<SafeAreaView style={styles.container} edges={['top', 'bottom']}>
<StatusBar style="auto" />
<SimpleHeader title="聊天设置" onBack={() => router.back()} />
<ScrollView
<ScrollView
contentContainerStyle={[
styles.scrollContent,
styles.scrollContent,
{ paddingHorizontal: responsivePadding, paddingBottom: 80 }
]}
>

View File

@@ -115,7 +115,7 @@ export const VerificationSettingsScreen: React.FC = () => {
contentContainerStyle={styles.scrollContent}
showsVerticalScrollIndicator={false}
>
{/* 状态卡片 */}
{/* 状态卡片 */}
<View style={styles.statusCard}>
<View style={[styles.statusIconContainer, { backgroundColor: statusConfig.color + '20' }]}>
<MaterialCommunityIcons