PC端的部分适配

This commit is contained in:
2026-03-16 17:47:10 +08:00
parent 798dd7c9a0
commit cb2087f779
30 changed files with 4242 additions and 438 deletions

View File

@@ -40,6 +40,8 @@ import { RootStackParamList, MessageStackParamList } from '../../navigation/type
import { getUserCache } from '../../services/database';
// 导入 EmbeddedChat 组件用于桌面端双栏布局
import { EmbeddedChat } from './components/EmbeddedChat';
// 导入 NotificationsScreen 用于在内部显示
import { NotificationsScreen } from './NotificationsScreen';
type NavigationProp = NativeStackNavigationProp<RootStackParamList>;
type MessageNavProp = NativeStackNavigationProp<MessageStackParamList>;
@@ -140,7 +142,15 @@ export const MessageListScreen: React.FC = () => {
const navigation = useNavigation<NavigationProp & MessageNavProp>();
const isFocused = useIsFocused();
const insets = useSafeAreaInsets();
const tabBarHeight = useBottomTabBarHeight();
// 在大屏幕模式下不使用 Bottom Tab Navigator所以不需要 tabBarHeight
const { isMobile } = useResponsive();
let tabBarHeight = 0;
try {
tabBarHeight = useBottomTabBarHeight();
} catch (e) {
// 大屏幕模式下不在 Bottom Tab Navigator 中,会抛出错误,忽略即可
tabBarHeight = 0;
}
const currentUserId = useAuthStore(state => state.currentUser?.id);
const setMessageUnreadCount = useUserStore(state => state.setMessageUnreadCount);
@@ -173,6 +183,30 @@ export const MessageListScreen: React.FC = () => {
const [activeSearchTab, setActiveSearchTab] = useState<'chat' | 'user'>('chat');
const [actionMenuVisible, setActionMenuVisible] = useState(false);
// 系统通知显示状态 - 用于在移动端显示通知页面
const [showNotifications, setShowNotifications] = useState(false);
// 系统消息会话对象(用于选中状态)
const systemMessageConversation: ConversationResponse = useMemo(() => ({
id: SYSTEM_MESSAGE_CHANNEL_ID,
type: 'private',
last_seq: 0,
last_message: {
id: '0',
conversation_id: SYSTEM_MESSAGE_CHANNEL_ID,
sender_id: 'system',
seq: 0,
segments: [{ type: 'text', data: { text: '系统通知' } }],
status: 'normal',
created_at: new Date().toISOString(),
},
last_message_at: new Date().toISOString(),
unread_count: systemUnreadCount,
participants: [],
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
}), [systemUnreadCount]);
// 动画值
const [scaleAnims] = useState(() =>
Array.from({ length: 20 }, () => new Animated.Value(1))
@@ -272,19 +306,19 @@ export const MessageListScreen: React.FC = () => {
}),
]).start(() => {
if (conversation.id === SYSTEM_MESSAGE_CHANNEL_ID) {
// 跳转到系统通知页面 - 使用正确的导航路径
// 系统通知 - 根据屏幕宽度决定如何显示
if (isWideScreen) {
// 宽屏下直接导航到通知页面
navigation.navigate('Notifications' as never);
// 宽屏下使用内部状态显示通知页面,同时设置系统消息为选中状态
setSelectedConversation(systemMessageConversation);
setShowNotifications(true);
} else {
// 窄屏下使用 Tab 导航
(navigation as any).navigate('Main', {
screen: 'MessageTab',
params: { screen: 'Notifications' }
});
// 窄屏下使用内部状态显示通知页面
setShowNotifications(true);
}
} else if (isWideScreen) {
// 【桌面端双栏布局】宽屏下设置选中会话,在右侧显示聊天
// 同时关闭系统通知页面
setShowNotifications(false);
setSelectedConversation(conversation);
} else if (conversation.type === 'group' && conversation.group) {
// 群聊 - 窄屏下导航
@@ -765,6 +799,9 @@ export const MessageListScreen: React.FC = () => {
onChangeText={setSearchText}
autoFocus
returnKeyType="search"
// 确保光标可见
cursorColor={colors.primary.main}
selectionColor={`${colors.primary.main}40`}
/>
{searchText.length > 0 && (
<TouchableOpacity onPress={() => setSearchText('')}>
@@ -903,7 +940,10 @@ export const MessageListScreen: React.FC = () => {
{/* 右侧内容区域 - 使用 flex:1 填充剩余空间 */}
<View style={styles.chatArea}>
{selectedConversation ? (
{showNotifications ? (
// 显示系统通知页面
<NotificationsScreen onBack={() => setShowNotifications(false)} />
) : selectedConversation ? (
// 显示选中会话的聊天内容
<EmbeddedChat
conversation={selectedConversation}
@@ -927,16 +967,17 @@ export const MessageListScreen: React.FC = () => {
return (
<SafeAreaView style={styles.container} edges={['top']}>
{isSearchMode ? (
{showNotifications ? (
// 显示系统通知页面,传入 onBack 回调
<NotificationsScreen onBack={() => setShowNotifications(false)} />
) : isSearchMode ? (
renderSearchMode()
) : isWideScreen ? (
<ResponsiveContainer maxWidth={800}>
{renderConversationList()}
</ResponsiveContainer>
) : (
isWideScreen ? (
<ResponsiveContainer maxWidth={800}>
{renderConversationList()}
</ResponsiveContainer>
) : (
renderConversationList()
)
renderConversationList()
)}
{renderActionMenu()}
</SafeAreaView>
@@ -1101,7 +1142,7 @@ const styles = StyleSheet.create({
...shadows.sm,
},
conversationItemSelected: {
backgroundColor: '#E3F2FD',
backgroundColor: colors.primary.light + '20',
borderColor: colors.primary.main,
borderWidth: 1,
},