feat(ui): unify design system to Twitter/X style across screens and improve message handling
Some checks failed
Frontend CI / build-and-push-web (push) Failing after 3m9s
Frontend CI / ota-android (push) Successful in 10m29s
Frontend CI / build-android-apk (push) Successful in 43m4s

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:
lafay
2026-04-25 00:39:40 +08:00
parent e0d28535f4
commit ad19bc2af7
26 changed files with 950 additions and 1121 deletions

View File

@@ -157,32 +157,27 @@ function createConversationRowStyles(colors: AppColors) {
alignItems: 'center',
paddingHorizontal: spacing.md,
paddingVertical: 14,
backgroundColor: colors.background.paper,
marginHorizontal: spacing.md,
marginTop: spacing.sm,
borderRadius: borderRadius.lg,
borderWidth: 0.5,
borderColor: colors.divider + '40',
backgroundColor: colors.background.default,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: colors.chat.borderLight,
},
conversationItemSelected: {
backgroundColor: colors.primary.light + '12',
borderColor: colors.primary.main + '60',
borderWidth: 1.5,
backgroundColor: colors.chat.surfaceMuted,
},
avatarContainer: {
position: 'relative',
},
systemAvatar: {
width: 50,
height: 50,
borderRadius: borderRadius.md,
width: 56,
height: 56,
borderRadius: borderRadius.full,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: colors.primary.main,
},
conversationContent: {
flex: 1,
marginLeft: spacing.md,
marginLeft: spacing.lg,
},
conversationHeader: {
flexDirection: 'row',
@@ -197,49 +192,49 @@ function createConversationRowStyles(colors: AppColors) {
officialBadge: {
backgroundColor: colors.primary.main,
borderRadius: borderRadius.sm,
paddingHorizontal: 6,
paddingVertical: 2,
paddingHorizontal: 5,
paddingVertical: 1,
marginRight: spacing.xs,
},
officialBadgeText: {
color: colors.primary.contrast,
fontSize: 10,
fontSize: 9,
fontWeight: '800',
},
userName: {
fontWeight: '700',
fontWeight: '600',
color: colors.text.primary,
fontSize: 16,
letterSpacing: 0.3,
letterSpacing: 0.2,
},
groupIcon: {
marginRight: 4,
marginRight: 3,
},
memberCount: {
fontSize: 12,
fontSize: 13,
color: colors.text.secondary,
marginLeft: 2,
fontWeight: '500',
},
pinnedIcon: {
marginLeft: 6,
marginLeft: 5,
},
groupAvatar: {
width: 50,
height: 50,
width: 56,
height: 56,
},
groupAvatarPlaceholder: {
width: 50,
height: 50,
width: 56,
height: 56,
borderRadius: borderRadius.md,
backgroundColor: colors.primary.main,
alignItems: 'center',
justifyContent: 'center',
},
timeText: {
color: colors.text.secondary,
color: colors.text.hint,
fontSize: 12,
fontWeight: '500',
fontWeight: '400',
},
messageRow: {
flexDirection: 'row',
@@ -250,25 +245,26 @@ function createConversationRowStyles(colors: AppColors) {
color: colors.text.secondary,
fontSize: 14,
fontWeight: '400',
lineHeight: 20,
},
unreadMessageText: {
color: colors.text.primary,
fontWeight: '600',
},
unreadBadge: {
minWidth: 22,
height: 22,
borderRadius: 11,
backgroundColor: colors.primary.main,
minWidth: 20,
height: 20,
borderRadius: 10,
backgroundColor: colors.error.main,
alignItems: 'center',
justifyContent: 'center',
marginLeft: spacing.sm,
paddingHorizontal: 6,
paddingHorizontal: 5,
},
unreadBadgeText: {
color: colors.primary.contrast,
color: '#FFFFFF',
fontSize: 12,
fontWeight: '800',
fontWeight: '700',
},
});
}
@@ -321,12 +317,12 @@ const ConversationListRowInner: React.FC<ConversationListRowProps> = ({
<View style={styles.avatarContainer}>
{isSystemChannel ? (
<View style={styles.systemAvatar}>
<MaterialCommunityIcons name="bell-ring" size={24} color={colors.primary.contrast} />
<MaterialCommunityIcons name="bell-ring" size={26} color={colors.primary.contrast} />
</View>
) : isGroupChat ? (
<View style={styles.groupAvatar}>
{displayAvatar ? (
<Avatar source={displayAvatar} size={50} name={displayName} />
<Avatar source={displayAvatar} size={56} name={displayName} />
) : (
<View style={styles.groupAvatarPlaceholder}>
<MaterialCommunityIcons name="account-group" size={28} color={colors.primary.contrast} />
@@ -334,7 +330,7 @@ const ConversationListRowInner: React.FC<ConversationListRowProps> = ({
)}
</View>
) : (
<Avatar source={displayAvatar} size={50} name={displayName} />
<Avatar source={displayAvatar} size={56} name={displayName} />
)}
</View>