feat(ui): unify design system to Twitter/X style across screens and improve message handling
Redesign multiple screens and components from card-based responsive design to Twitter/X flat design: - UserProfileHeader: adopt Twitter/X style with larger icons, simplified buttons, and block functionality - AppBackButton: update to chevron-left icon with larger size, remove background styling - Update SettingsScreen, EditProfileScreen, and UserProfileScreen with flat layout approach - ConversationListRow: convert from bordered cards to flat list rows with updated typography Improve message system with WebSocket notification handling: - Add real-time system unread count updates via WebSocket - Track lastSystemMessageAt for accurate system message timestamps - Add notification deduplication and read-status filtering - Combine system and conversation unread counts in background sync - Clear system notifications from notification center on mark as read
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 统一的用户主页组件
|
||||
* 威友 - 支持两种模式:self(当前用户)和 other(其他用户)
|
||||
* 采用现代卡片式设计,优化视觉层次和交互体验
|
||||
* 统一的用户主页组件 - Twitter/X 风格
|
||||
* 支持两种模式:self(当前用户)和 other(其他用户)
|
||||
* 采用 Twitter/X 扁平化设计,全宽布局,无边框卡片
|
||||
* 支持桌面端双栏布局
|
||||
*/
|
||||
|
||||
@@ -29,7 +29,7 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
const colors = useAppColors();
|
||||
const sharedStyles = useMemo(() => createSharedProfileStyles(colors), [colors]);
|
||||
const { isDesktop, isTablet } = useResponsive();
|
||||
|
||||
|
||||
const {
|
||||
user,
|
||||
posts,
|
||||
@@ -45,14 +45,15 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
handleFollowingPress,
|
||||
handleFollowersPress,
|
||||
handleMessage,
|
||||
handleMore,
|
||||
handleBlock,
|
||||
isBlocked,
|
||||
handleSettings,
|
||||
handleEditProfile,
|
||||
isCurrentUser,
|
||||
currentUser,
|
||||
} = useUserProfile({ mode, userId, isDesktop, isTablet });
|
||||
|
||||
// 渲染帖子列表
|
||||
|
||||
// 渲染帖子列表 - Twitter 风格无边框
|
||||
const renderPostList = useCallback((postList: Post[], emptyTitle: string, emptyDesc: string) => {
|
||||
if (postList.length === 0) {
|
||||
return (
|
||||
@@ -64,7 +65,7 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<View style={sharedStyles.postsContainer}>
|
||||
{postList.map((post, index) => {
|
||||
@@ -85,11 +86,11 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
</View>
|
||||
);
|
||||
}, [currentUser?.id, handlePostAction, activeTab]);
|
||||
|
||||
|
||||
// 渲染内容
|
||||
const renderContent = useCallback(() => {
|
||||
if (loading) return <Loading />;
|
||||
|
||||
|
||||
if (activeTab === 0) {
|
||||
return renderPostList(
|
||||
posts,
|
||||
@@ -97,7 +98,7 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
mode === 'self' ? '分享你的想法,发布第一条帖子吧' : ''
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (activeTab === 1) {
|
||||
return renderPostList(
|
||||
favorites,
|
||||
@@ -105,29 +106,30 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
mode === 'self' ? '发现喜欢的内容,点击收藏按钮保存' : ''
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}, [loading, activeTab, posts, favorites, mode, renderPostList]);
|
||||
|
||||
|
||||
// 渲染用户信息头部
|
||||
const renderUserHeader = useMemo(() => {
|
||||
if (!user) return null;
|
||||
|
||||
|
||||
return (
|
||||
<UserProfileHeader
|
||||
user={user}
|
||||
isCurrentUser={isCurrentUser}
|
||||
isBlocked={isBlocked}
|
||||
onFollow={handleFollow}
|
||||
onSettings={handleSettings}
|
||||
onEditProfile={handleEditProfile}
|
||||
onMessage={handleMessage}
|
||||
onMore={handleMore}
|
||||
onBlock={handleBlock}
|
||||
onFollowingPress={handleFollowingPress}
|
||||
onFollowersPress={handleFollowersPress}
|
||||
/>
|
||||
);
|
||||
}, [user, isCurrentUser, handleFollow, handleSettings, handleEditProfile, handleMessage, handleMore, handleFollowingPress, handleFollowersPress]);
|
||||
|
||||
}, [user, isCurrentUser, isBlocked, handleFollow, handleSettings, handleEditProfile, handleMessage, handleBlock, handleFollowingPress, handleFollowersPress]);
|
||||
|
||||
// 渲染 TabBar 和内容
|
||||
const renderTabBarAndContent = useMemo(() => (
|
||||
<>
|
||||
@@ -145,7 +147,7 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
</View>
|
||||
</>
|
||||
), [activeTab, renderContent]);
|
||||
|
||||
|
||||
// 未登录/用户不存在状态
|
||||
if (mode === 'self' && !currentUser) {
|
||||
return (
|
||||
@@ -158,7 +160,7 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (mode === 'other' && !user && !loading) {
|
||||
return (
|
||||
<SafeAreaView style={sharedStyles.container} edges={['bottom']}>
|
||||
@@ -170,14 +172,14 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const safeAreaEdges = hasHeader ? ['bottom'] : (mode === 'self' ? ['top', 'bottom'] : ['bottom']);
|
||||
|
||||
|
||||
// 桌面端使用双栏布局
|
||||
if (isDesktop || isTablet) {
|
||||
return (
|
||||
<SafeAreaView style={sharedStyles.container} edges={safeAreaEdges as any}>
|
||||
<ResponsiveContainer maxWidth={1400}>
|
||||
<ResponsiveContainer maxWidth={1200}>
|
||||
<View style={sharedStyles.desktopContainer}>
|
||||
{/* 左侧:用户信息 */}
|
||||
<View style={sharedStyles.desktopSidebar}>
|
||||
@@ -196,7 +198,7 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
{renderUserHeader}
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
|
||||
{/* 右侧:帖子列表 */}
|
||||
<View style={sharedStyles.desktopContent}>
|
||||
<ScrollView
|
||||
@@ -211,7 +213,7 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 移动端使用单栏布局
|
||||
return (
|
||||
<SafeAreaView style={sharedStyles.container} edges={safeAreaEdges as any}>
|
||||
@@ -234,4 +236,4 @@ export const UserProfileScreen: React.FC<UserProfileScreenProps> = ({ mode, user
|
||||
);
|
||||
};
|
||||
|
||||
export default UserProfileScreen;
|
||||
export default UserProfileScreen;
|
||||
|
||||
Reference in New Issue
Block a user