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

@@ -26,18 +26,20 @@ import {
ActivityIndicator,
KeyboardAvoidingView,
Platform,
TouchableOpacity,
} from 'react-native';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { useNavigation, useRouter } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { Text, ImageGallery, ImageGridItem } from '../../components/common';
import { colors } from '../../theme';
import { useAppColors } from '../../theme';
import * as hrefs from '../../navigation/hrefs';
import { messageManager } from '../../stores';
import { useBreakpointGTE } from '../../hooks/useResponsive';
import {
useChatScreen,
chatScreenStyles as baseStyles,
useChatScreenStyles,
EmojiPanel,
MorePanel,
MentionPanel,
@@ -53,10 +55,11 @@ export const ChatScreen: React.FC = () => {
const navigation = useNavigation();
const router = useRouter();
const insets = useSafeAreaInsets();
const colors = useAppColors();
const styles = useChatScreenStyles();
// 响应式布局
const isWideScreen = useBreakpointGTE('lg');
const styles = baseStyles;
// 监听屏幕宽度变化当变为大屏幕时自动跳转到web端首页
useEffect(() => {
@@ -79,6 +82,8 @@ export const ChatScreen: React.FC = () => {
beforeHeight: 0,
});
const preloadCooldownTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const showJumpToLatestRef = useRef(false);
const [showJumpToLatest, setShowJumpToLatest] = useState(false);
const containerStyle = useMemo(() => ([
styles.container,
@@ -200,6 +205,7 @@ export const ChatScreen: React.FC = () => {
loadMoreHistory,
handleMessageListContentSizeChange,
handleReachLatestEdge,
jumpToLatestMessages,
setBrowsingHistory,
} = useChatScreen();
const displayMessages = useMemo(() => [...messages].reverse(), [messages]);
@@ -210,6 +216,18 @@ export const ChatScreen: React.FC = () => {
}
}, [loadingMore, showEdgeLoadingIndicator]);
useEffect(() => {
if (loading) {
showJumpToLatestRef.current = false;
setShowJumpToLatest(false);
}
}, [loading]);
useEffect(() => {
showJumpToLatestRef.current = false;
setShowJumpToLatest(false);
}, [conversationId]);
useEffect(() => {
return () => {
if (preloadCooldownTimerRef.current) {
@@ -314,6 +332,14 @@ export const ChatScreen: React.FC = () => {
viewportHeight: layoutMeasurement.height,
};
// invertedoffset 越大离最新消息端越远,与 setBrowsingHistory(120) 阈值一致
const shouldShowJump =
contentOffset.y > 120 && !loading && messages.length > 0;
if (showJumpToLatestRef.current !== shouldShowJump) {
showJumpToLatestRef.current = shouldShowJump;
setShowJumpToLatest(shouldShowJump);
}
// 离开最新消息端后进入“浏览历史”模式,屏蔽自动跟随到底
if (contentOffset.y > 120) {
setBrowsingHistory(true);
@@ -360,7 +386,17 @@ export const ChatScreen: React.FC = () => {
}, 350);
});
}
}, [scrollPositionRef, hasMoreHistory, loadingMore, loading, loadMoreHistory, handleReachLatestEdge, showEdgeLoadingIndicator, setBrowsingHistory]);
}, [
scrollPositionRef,
hasMoreHistory,
loadingMore,
loading,
messages.length,
loadMoreHistory,
handleReachLatestEdge,
showEdgeLoadingIndicator,
setBrowsingHistory,
]);
const handleContentSizeChange = useCallback((contentWidth: number, contentHeight: number) => {
handleMessageListContentSizeChange(contentWidth, contentHeight);
@@ -474,6 +510,18 @@ export const ChatScreen: React.FC = () => {
</View>
</View>
)}
{showJumpToLatest && (
<TouchableOpacity
style={styles.jumpToLatestFab}
onPress={jumpToLatestMessages}
activeOpacity={0.85}
accessibilityRole="button"
accessibilityLabel="回到最新消息"
>
<MaterialCommunityIcons name="chevron-down" size={20} color={colors.primary.main} />
<Text style={styles.jumpToLatestFabText}></Text>
</TouchableOpacity>
)}
</View>
{/* 底部区域:输入框 + 面板 */}