diff --git a/src/components/business/CommentItem.tsx b/src/components/business/CommentItem.tsx index b8fb632..707929b 100644 --- a/src/components/business/CommentItem.tsx +++ b/src/components/business/CommentItem.tsx @@ -143,7 +143,6 @@ function createCommentItemStyles(colors: AppColors) { paddingVertical: spacing.xs, borderLeftWidth: 2, borderLeftColor: colors.divider, - backgroundColor: colors.background.default, }, subReplyItem: { flexDirection: 'row', @@ -154,8 +153,8 @@ function createCommentItemStyles(colors: AppColors) { marginBottom: 0, }, subReplyBody: { - fontSize: fontSizes.sm, - lineHeight: 20, + fontSize: fontSizes.md, + lineHeight: 22, marginTop: 2, }, subReplyContent: { @@ -177,10 +176,10 @@ function createCommentItemStyles(colors: AppColors) { paddingVertical: spacing.xs, }, replyToText: { - fontSize: fontSizes.xs, + fontSize: fontSizes.sm, }, replyToName: { - fontSize: fontSizes.xs, + fontSize: fontSizes.sm, fontWeight: '500', }, subReplyActions: { @@ -483,7 +482,7 @@ const CommentItem: React.FC = ({ {targetNickname && ( <> - {' '}回复 + {' '}回复{' '} {targetNickname} @@ -501,15 +500,6 @@ const CommentItem: React.FC = ({ {renderSubReplyImages(reply)} {/* 子评论操作按钮 */} - onReplyPress?.(reply)} - > - - - 回复 - - {/* 点赞按钮 */} = ({ > = ({ {reply.likes_count > 0 ? formatNumber(reply.likes_count) : '赞'} + onReplyPress?.(reply)} + > + + + 回复 + + {/* 删除按钮 - 子评论作者可见 */} {isSubReplyAuthor && ( = ({ > @@ -546,13 +545,12 @@ const CommentItem: React.FC = ({ )} - {/* 举报按钮 - 对非子评论作者显示 */} {!isSubReplyAuthor && onReport && ( onReport(reply)} > - + 举报 diff --git a/src/components/business/TradeCard/TradeCard.tsx b/src/components/business/TradeCard/TradeCard.tsx index ca9da18..243033d 100644 --- a/src/components/business/TradeCard/TradeCard.tsx +++ b/src/components/business/TradeCard/TradeCard.tsx @@ -41,6 +41,7 @@ function createTradeCardStyles(colors: AppColors) { position: 'relative', aspectRatio: 1, backgroundColor: colors.background.default, + minHeight: 140, }, listImageContainer: { width: 120, @@ -104,7 +105,9 @@ function createTradeCardStyles(colors: AppColors) { fontWeight: '600', }, gridContent: { - padding: spacing.sm, + paddingHorizontal: spacing.sm, + paddingTop: spacing.xs, + paddingBottom: spacing.sm, }, titleRow: { flexDirection: 'row', @@ -155,7 +158,7 @@ function createTradeCardStyles(colors: AppColors) { flexDirection: 'row', flexWrap: 'wrap', gap: 4, - marginTop: spacing.xs, + marginTop: 2, }, tag: { paddingHorizontal: 5, @@ -191,7 +194,7 @@ function createTradeCardStyles(colors: AppColors) { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', - marginTop: spacing.sm, + marginTop: spacing.xs, }, authorRow: { flexDirection: 'row', @@ -354,6 +357,9 @@ const TradeCardBase: React.FC = ({ item, variant = 'list', onPre ); } + // grid variant is used in masonry layout; list variant below is unused but kept for compatibility + + return ( { color?: string; numberOfLines?: number; onPress?: () => void; - style?: TextStyle | TextStyle[]; + style?: TextStyle | TextStyle[] | (TextStyle | undefined)[]; weight?: 'regular' | 'medium' | 'semibold' | 'bold'; } diff --git a/src/screens/apps/AppsScreen.tsx b/src/screens/apps/AppsScreen.tsx index 9aab6d2..efd6fd6 100644 --- a/src/screens/apps/AppsScreen.tsx +++ b/src/screens/apps/AppsScreen.tsx @@ -90,9 +90,6 @@ export const AppsScreen: React.FC = () => { const renderTiles = () => ( <> - - 与社区账号打通的轻应用入口 - {APP_ENTRIES.map(item => ( { renderItem={({ item }: { item: { key: string; label: string } }) => ( setMarketCategory(item.key as TradeCategory | 'all')} > (null); + const flashListRef = useRef>(null); // 网格列数:移动端2列,平板3列,桌面4列 const numColumns = useMemo(() => { @@ -83,12 +80,6 @@ export function MarketView({ return 2; }, [width]); - // 计算卡片宽度(用于固定宽高比) - const cardWidth = useMemo(() => { - const totalGap = gap * (numColumns - 1); - return Math.floor((width - padding * 2 - totalGap) / numColumns); - }, [width, padding, gap, numColumns]); - const fetchItems = useCallback(async (isRefresh = false) => { try { if (isRefresh) { @@ -172,7 +163,7 @@ export function MarketView({ }, [items, isAuth]); const renderItem = useCallback>(({ item }) => ( - + - ), [handlePressItem, handleFavorite, cardWidth, gap]); + ), [handlePressItem, handleFavorite, gap]); const keyExtractor = useCallback((item: TradeItemDTO) => item.id, []); @@ -217,6 +208,7 @@ export function MarketView({ } ListFooterComponent={isLoadingMore ? : null} drawDistance={250} + masonry /> ); diff --git a/src/screens/material/MaterialDetailScreen.tsx b/src/screens/material/MaterialDetailScreen.tsx index 0b7dacc..4f57785 100644 --- a/src/screens/material/MaterialDetailScreen.tsx +++ b/src/screens/material/MaterialDetailScreen.tsx @@ -1,5 +1,6 @@ /** * 资料详情页:展示资料详细信息 + * 现代化扁平化设计,风格统一 */ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { @@ -114,16 +115,17 @@ export const MaterialDetailScreen: React.FC = () => { }); }, []); + // 扁平化卡片样式:更柔和的阴影,更大的圆角 const cardStyle = useMemo( () => ({ backgroundColor: colors.background.paper, - borderRadius: borderRadius.lg, + borderRadius: borderRadius.xl, overflow: 'hidden' as const, - shadowColor: '#000', - shadowOffset: { width: 0, height: 1 }, - shadowOpacity: 0.04, - shadowRadius: 4, - elevation: 1, + shadowColor: colors.chat.shadow, + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.06, + shadowRadius: 8, + elevation: 2, }), [colors] ); @@ -159,14 +161,20 @@ export const MaterialDetailScreen: React.FC = () => { return ( <> - {/* 文件信息卡片 */} + {/* 文件信息卡片 - 现代化设计 */} + {/* 顶部文件类型标识区 - 扁平化渐变 */} - - - {fileTypeName} - + + + + + + {fileTypeName} + + + {material.title} @@ -176,16 +184,18 @@ export const MaterialDetailScreen: React.FC = () => { {material.description} )} + + {/* 元数据 - 现代化标签式布局 */} - - - + + + {formatFileSize(material.file_size)} - - - + + + {material.download_count} 次下载 @@ -193,46 +203,69 @@ export const MaterialDetailScreen: React.FC = () => { - {/* 详细信息 */} + {/* 详细信息卡片 - 扁平化列表 */} - - 详细信息 - - - - 文件名 - - - {material.file_name} + + + + + + 详细信息 - - - 上传时间 - - - {formatDate(material.created_at)} - - - {material.author_name && ( + + - - 上传者 - + + + + 文件名 + + - {material.author_name} + {material.file_name} - )} - {material.tags && material.tags.length > 0 && ( - - - 标签 + + + + + + 上传时间 + + + + {formatDate(material.created_at)} + + + {material.author_name && ( + + + + + 上传者 + + + + {material.author_name} + + + )} + + + {material.tags && material.tags.length > 0 && ( + + + + + 标签 + + {material.tags.map((tag, index) => ( - - + + {tag} @@ -242,24 +275,29 @@ export const MaterialDetailScreen: React.FC = () => { )} - {/* 操作按钮 */} + {/* 操作按钮 - 现代化扁平按钮 */} - + + + 在线预览 + - + + + 下载资料 @@ -273,7 +311,7 @@ export const MaterialDetailScreen: React.FC = () => { - {/* Header */} + {/* Header - 扁平化设计 */} router.back()} /> @@ -284,15 +322,15 @@ export const MaterialDetailScreen: React.FC = () => { - - + + {/* Content */} {isWideScreen ? ( - + = ({ return ( - - - - + + + + + {isGroupChat ? ( + + ) : ( + + )} + + - {isGroupChat ? ( - <> - - - - - {getDisplayTitle()} - - {groupInfo?.member_count || 0}位成员 - {typingHint && ( - {typingHint} - )} - - - - ) : ( - <> - - - {getDisplayTitle()} + + {getDisplayTitle()} + {isGroupChat ? ( + + {groupInfo?.member_count || 0}位成员 {typingHint && ( - - {typingHint} - + {typingHint} )} - - )} + ) : ( + typingHint && ( + + {typingHint} + + ) + )} + - + {/* 大屏幕 + 群聊时显示群信息按钮,否则显示三点菜单 */} {isWideScreen && isGroupChat && onGroupInfoPress ? ( = ({ ...baseStyles, emojiContainer: { flex: 1, - padding: spacing.sm, + paddingTop: spacing.sm, + paddingHorizontal: spacing.sm, + backgroundColor: baseStyles.panelContainer.backgroundColor, }, emojiItem: { width: 40, @@ -281,21 +283,19 @@ export const EmojiPanel: React.FC = ({ ); }; - // 渲染管理按钮(表情面板第一位)- 现代扁平化设计 + // 渲染管理按钮(表情面板第一位)- 填满格子 const renderManageButton = () => ( - - - + ); @@ -561,24 +561,28 @@ export const EmojiPanel: React.FC = ({ {activeTab === 'emoji' ? renderEmojiPanel() : renderStickerPanel()} - {/* 底部 Tab 栏 - 现代胶囊式设计 */} + {/* 底部 Tab 栏 - QQ/微信风格横向导航 */} - + setActiveTab('emoji')} activeOpacity={0.8} - > - 😊 - - setActiveTab('sticker')} - activeOpacity={0.8} > + + setActiveTab('sticker')} + activeOpacity={0.8} + > + diff --git a/src/screens/message/components/ChatScreen/styles.ts b/src/screens/message/components/ChatScreen/styles.ts index 20f6f4d..ff2a25e 100644 --- a/src/screens/message/components/ChatScreen/styles.ts +++ b/src/screens/message/components/ChatScreen/styles.ts @@ -105,6 +105,12 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { backgroundColor: cardBgColor, height: 56, }, + headerLeft: { + flexDirection: 'row', + alignItems: 'center', + gap: spacing.xs, + zIndex: 2, + }, backButton: { width: 40, height: 40, @@ -114,27 +120,21 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { padding: 0, }, headerCenter: { - flex: 1, + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, alignItems: 'center', - marginHorizontal: spacing.sm, + justifyContent: 'center', + paddingHorizontal: 50, }, titleRow: { flexDirection: 'row', alignItems: 'center', - gap: spacing.sm, - paddingHorizontal: spacing.sm, paddingVertical: spacing.xs, borderRadius: 8, }, - titleLeading: { - width: 36, - height: 36, - borderRadius: 10, - alignItems: 'center', - justifyContent: 'center', - backgroundColor: panelBgColor, - overflow: 'hidden', - }, groupAvatar: { width: 36, height: 36, @@ -429,17 +429,17 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { // 输入框区域 - 与列表背景同色底栏,顶部细分隔 inputWrapper: { - backgroundColor: screenBgColor, + backgroundColor: cardBgColor, borderTopWidth: StyleSheet.hairlineWidth, - borderTopColor: colors.chat.border, + borderTopColor: colors.chat.borderHairline, }, inputContainer: { backgroundColor: 'transparent', borderWidth: 0, borderRadius: 0, marginHorizontal: 10, - marginBottom: 10, - marginTop: 2, + marginBottom: 6, + marginTop: 6, paddingHorizontal: spacing.sm, paddingVertical: spacing.sm, shadowColor: 'transparent', @@ -451,7 +451,7 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { inputInner: { flexDirection: 'row', alignItems: 'center', - backgroundColor: inputBgColor, + backgroundColor: colors.chat.surfaceRaised, borderRadius: 20, paddingHorizontal: spacing.xs, paddingVertical: 4, @@ -464,7 +464,7 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { elevation: 0, }, inputInnerMuted: { - backgroundColor: colors.chat.borderHairline, + backgroundColor: colors.chat.surfaceMuted, opacity: 0.7, }, @@ -585,14 +585,9 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { // 面板 panelWrapper: { - backgroundColor: panelBgColor, - borderTopWidth: 1, - borderTopColor: colors.chat.border, - shadowColor: colors.chat.shadow, - shadowOffset: { width: 0, height: -2 }, - shadowOpacity: 0.1, - shadowRadius: 8, - elevation: 8, + backgroundColor: cardBgColor, + borderTopWidth: StyleSheet.hairlineWidth, + borderTopColor: colors.chat.borderHairline, }, // 表情面板包装器 - 底部 tab 栏是白色,安全区域也用白色填充 emojiPanelWrapper: { @@ -600,7 +595,11 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { }, panelContainer: { flex: 1, - backgroundColor: panelBgColor, + backgroundColor: cardBgColor, + }, + morePanelBackground: { + flex: 1, + backgroundColor: cardBgColor, }, // 表情面板 @@ -611,6 +610,7 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { paddingTop: spacing.md, paddingBottom: spacing.xl, alignItems: 'flex-start', + backgroundColor: cardBgColor, }, emojiItem: { width: '12.5%', @@ -636,55 +636,41 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { flex: 1, }, - // Tab 栏 - 现代胶囊式设计 + // Tab 栏 - 底部横向导航条(QQ/微信风格) panelTabBar: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', - paddingHorizontal: spacing.md, - paddingVertical: spacing.sm + 2, + paddingHorizontal: 0, + paddingVertical: 0, + backgroundColor: cardBgColor, borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: colors.chat.borderHairline, - backgroundColor: cardBgColor, }, - panelTabContainer: { + panelTabScroll: { + flex: 1, flexDirection: 'row', alignItems: 'center', - backgroundColor: panelBgColor, - borderRadius: 12, - padding: 3, + paddingHorizontal: spacing.sm, + gap: spacing.sm, }, - panelTab: { - width: 42, - height: 36, + panelTabItem: { alignItems: 'center', justifyContent: 'center', - borderRadius: 10, + width: 48, + height: 44, + borderBottomWidth: 2.5, + borderBottomColor: 'transparent', }, - panelTabActive: { - backgroundColor: cardBgColor, - shadowColor: colors.chat.shadow, - shadowOffset: { width: 0, height: 1 }, - shadowOpacity: 0.08, - shadowRadius: 2, - elevation: 1, - }, - panelTabEmoji: { - fontSize: 22, - }, - panelTabDivider: { - width: 1, - height: 20, - backgroundColor: colors.chat.border, - marginHorizontal: spacing.sm, + panelTabItemActive: { + borderBottomColor: colors.primary.main, }, panelCloseButton: { - width: 36, - height: 36, + width: 44, + height: 44, alignItems: 'center', justifyContent: 'center', - borderRadius: 10, - backgroundColor: panelBgColor, + marginRight: spacing.sm, }, // 自定义表情面板 @@ -692,12 +678,14 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { flex: 1, justifyContent: 'center', alignItems: 'center', + backgroundColor: cardBgColor, }, stickerEmptyContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: spacing.xl, + backgroundColor: cardBgColor, }, stickerEmptyText: { fontSize: 16, @@ -715,6 +703,7 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { paddingHorizontal: spacing.md, paddingTop: spacing.md, paddingBottom: spacing.xl, + backgroundColor: cardBgColor, }, stickerItem: { width: (SCREEN_WIDTH - spacing.md * 2) / 4 - 8, @@ -734,9 +723,10 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { flexDirection: 'row', flexWrap: 'wrap', paddingHorizontal: spacing.lg + 4, - paddingTop: spacing.lg, + paddingTop: spacing.md, paddingBottom: spacing.xl, justifyContent: 'flex-start', + backgroundColor: cardBgColor, }, moreItem: { width: (SCREEN_WIDTH - spacing.lg * 2 - 8) / 4, @@ -779,12 +769,6 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { fontWeight: '500', letterSpacing: 0.3, }, - // MorePanel 整体背景 - morePanelBackground: { - flex: 1, - backgroundColor: panelBgColor, - }, - // @成员选择浮层 - 绝对定位浮在输入框上方 mentionPanelFloat: { position: 'absolute', diff --git a/src/screens/profile/AboutScreen.tsx b/src/screens/profile/AboutScreen.tsx index ad0d18e..f6a9ef2 100644 --- a/src/screens/profile/AboutScreen.tsx +++ b/src/screens/profile/AboutScreen.tsx @@ -524,9 +524,6 @@ export const AboutScreen: React.FC = () => { > - - 萝卜 - {APP_NAME} {APP_SLOGAN} 版本 {APP_VERSION} diff --git a/src/screens/profile/PrivacyPolicyScreen.tsx b/src/screens/profile/PrivacyPolicyScreen.tsx index 76f3e31..8d8a4bf 100644 --- a/src/screens/profile/PrivacyPolicyScreen.tsx +++ b/src/screens/profile/PrivacyPolicyScreen.tsx @@ -52,12 +52,8 @@ const PRIVACY_SECTIONS = [ 1.2 我们在您使用服务时收集的信息 • 设备信息:包括设备型号、操作系统版本、设备设置、唯一设备标识符(如IMEI、Android ID、IDFA、OAID、MAC地址等)、IP地址等 • 日志信息:IP地址、访问时间、浏览记录、操作日志等 -• 位置信息:为了向您提供"校园圈"、"附近的人"等基于位置的服务,经您授权,我们会收集您的精确地理位置信息。该信息属于敏感个人信息,拒绝提供仅会影响相关功能,不影响其他服务的使用 • 相机/相册权限:用于发布动态、更换头像。我们仅在您主动触发相关功能时申请权限,且不会在后台持续收集 -• 通讯录权限:经您授权后用于查找好友 - -1.3 从第三方获取的信息 -如您使用第三方账号登录功能(具体以应用实际提供的登录方式为准),我们会从第三方获取您授权共享的账号信息(如昵称、头像等)。`, +• 通讯录权限:经您授权后用于查找好友`, }, { title: '二、我们如何使用信息', diff --git a/src/screens/profile/PrivacySettingsScreen.tsx b/src/screens/profile/PrivacySettingsScreen.tsx index 0ae3a08..ce66ff2 100644 --- a/src/screens/profile/PrivacySettingsScreen.tsx +++ b/src/screens/profile/PrivacySettingsScreen.tsx @@ -18,10 +18,10 @@ import type { PrivacySettingsDTO, VisibilityLevel } from '../../types/dto'; const CONTENT_MAX_WIDTH = 720; -const VISIBILITY_OPTIONS: { value: VisibilityLevel; label: string; description: string }[] = [ - { value: 'everyone', label: '所有人可见', description: '任何人都可查看' }, - { value: 'following', label: '仅关注的人可见', description: '只有你关注的人可查看' }, - { value: 'self', label: '仅自己可见', description: '只有自己可查看' }, +const VISIBILITY_OPTIONS: { value: VisibilityLevel; label: string }[] = [ + { value: 'everyone', label: '所有人可见' }, + { value: 'following', label: '仅关注的人可见' }, + { value: 'self', label: '仅自己可见' }, ]; const PRIVACY_ITEMS: { key: keyof PrivacySettingsDTO; title: string; description: string }[] = [ @@ -65,55 +65,78 @@ function createPrivacySettingsStyles(colors: AppColors) { textTransform: 'uppercase', letterSpacing: 0.5, }, - // 隐私设置项 - 扁平化卡片风格 + // 扁平式布局:整行横向排列,底部边框分隔 item: { - backgroundColor: colors.background.default, - borderRadius: 14, - padding: spacing.lg, - marginHorizontal: spacing['2xl'], - marginBottom: spacing.md, - }, - itemHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', - marginBottom: spacing.sm, + paddingVertical: spacing.lg, + marginHorizontal: spacing['2xl'], + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: colors.divider, + }, + itemLast: { + borderBottomWidth: 0, + }, + itemTextWrap: { + flex: 1, + marginRight: spacing.md, }, itemTitle: { fontWeight: '600', fontSize: fontSizes.md, color: colors.text.primary, + marginBottom: spacing.xs, }, itemDescription: { fontSize: fontSizes.sm, color: colors.text.secondary, - marginBottom: spacing.md, }, - optionsRow: { + // 无背景色的选择框,紧贴右侧 + selectBox: { flexDirection: 'row', - flexWrap: 'wrap', - gap: spacing.sm, + alignItems: 'center', + paddingVertical: spacing.xs, }, - // 选项按钮 - 扁平化风格 - optionButton: { + selectBoxText: { + fontSize: fontSizes.sm, + color: colors.text.secondary, + marginRight: spacing.xs, + }, + // 原位展开的下拉菜单 + dropdownMenu: { + position: 'absolute', + right: 0, + top: '100%', + marginTop: 4, + backgroundColor: colors.background.paper, + borderRadius: borderRadius.md, + borderWidth: StyleSheet.hairlineWidth, + borderColor: colors.divider, + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.1, + shadowRadius: 4, + elevation: 4, + zIndex: 100, + minWidth: 160, + }, + dropdownOption: { paddingHorizontal: spacing.md, paddingVertical: spacing.sm, - borderRadius: borderRadius.full, - borderWidth: 1, - borderColor: colors.divider, - backgroundColor: colors.background.paper, + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: colors.divider, }, - optionButtonActive: { - backgroundColor: colors.primary.main, - borderColor: colors.primary.main, + dropdownOptionLast: { + borderBottomWidth: 0, }, - optionText: { - fontSize: 13, + dropdownOptionText: { + fontSize: fontSizes.sm, color: colors.text.primary, }, - optionTextActive: { - color: colors.text.inverse, - fontWeight: '500', + dropdownOptionTextActive: { + color: colors.primary.main, + fontWeight: '600', }, }); } @@ -127,6 +150,7 @@ export const PrivacySettingsScreen: React.FC = () => { const [settings, setSettings] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); + const [openPicker, setOpenPicker] = useState(null); const responsivePadding = useResponsiveSpacing({ xs: 8, sm: 12, md: 16, lg: 24, xl: 32 }); const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.md; @@ -150,10 +174,10 @@ export const PrivacySettingsScreen: React.FC = () => { const updateSetting = useCallback(async (key: keyof PrivacySettingsDTO, value: VisibilityLevel) => { if (!settings) return; - + const newSettings = { ...settings, [key]: value }; setSettings(newSettings); - + setSaving(true); try { const ok = await authService.updatePrivacySettings({ @@ -171,6 +195,9 @@ export const PrivacySettingsScreen: React.FC = () => { } }, [settings]); + const getLabel = (value?: VisibilityLevel) => + VISIBILITY_OPTIONS.find((o) => o.value === value)?.label ?? '请选择'; + if (loading) { return ( @@ -186,42 +213,75 @@ export const PrivacySettingsScreen: React.FC = () => { - - - 隐私设置 - - - - {PRIVACY_ITEMS.map((item) => ( - - - {item.title} - - - {item.description} - - - {VISIBILITY_OPTIONS.map((option) => { - const isActive = settings?.[item.key] === option.value; - return ( - updateSetting(item.key, option.value)} - activeOpacity={0.7} - > - - {option.label} - - - ); - })} + {PRIVACY_ITEMS.map((item, index) => { + const isOpen = openPicker === item.key; + return ( + + + + {item.title} + + + {item.description} + + + + setOpenPicker(isOpen ? null : item.key)} + activeOpacity={0.7} + > + + {getLabel(settings?.[item.key])} + + + + + {/* 原位展开的下拉选项 */} + {isOpen && ( + + {VISIBILITY_OPTIONS.map((option, optIndex) => { + const isActive = settings?.[item.key] === option.value; + return ( + { + updateSetting(item.key, option.value); + setOpenPicker(null); + }} + activeOpacity={0.7} + > + + {option.label} + + + ); + })} + + )} - - ))} + ); + })} diff --git a/src/screens/trade/CreateTradeScreen.tsx b/src/screens/trade/CreateTradeScreen.tsx index 34ae0fd..e1a846b 100644 --- a/src/screens/trade/CreateTradeScreen.tsx +++ b/src/screens/trade/CreateTradeScreen.tsx @@ -466,9 +466,9 @@ export function CreateTradeScreen({ onClose, onSuccess, editItem }: CreateTradeS > {/* 标题区域 */} - {isEdit ? '编辑商品' : '发布商品'} + {isEdit ? '编辑' + (tradeType === 'buy' ? '收购' : '商品') : '发布' + (tradeType === 'buy' ? '收购' : '商品')} - 填写商品信息,让更多人看到 + {tradeType === 'buy' ? '填写收购需求,让卖家主动联系你' : '填写商品信息,让更多人看到'} {/* 交易类型 */} @@ -520,7 +520,7 @@ export function CreateTradeScreen({ onClose, onSuccess, editItem }: CreateTradeS style={styles.input} value={title} onChangeText={setTitle} - placeholder="描述你的商品" + placeholder={tradeType === 'buy' ? '描述你想收购的商品' : '描述你的商品'} placeholderTextColor={colors.text.hint} maxLength={100} cursorColor={colors.primary.main} @@ -541,7 +541,7 @@ export function CreateTradeScreen({ onClose, onSuccess, editItem }: CreateTradeS style={[styles.input, styles.textArea]} value={content} onChangeText={setContent} - placeholder="详细描述商品情况..." + placeholder={tradeType === 'buy' ? '详细描述收购需求、预算、成色要求等...' : '详细描述商品情况...'} placeholderTextColor={colors.text.hint} multiline maxLength={2000} diff --git a/src/screens/trade/TradeDetailScreen.tsx b/src/screens/trade/TradeDetailScreen.tsx index 9a26ce9..f2f29ba 100644 --- a/src/screens/trade/TradeDetailScreen.tsx +++ b/src/screens/trade/TradeDetailScreen.tsx @@ -120,6 +120,11 @@ function createStyles(colors: AppColors) { fontWeight: '700', color: '#FF4D4F', }, + priceSymbol: { + fontSize: fontSizes.md, + fontWeight: '700', + color: '#FF4D4F', + }, titleRow: { flexDirection: 'row', @@ -330,6 +335,17 @@ function createStyles(colors: AppColors) { color: colors.text.primary, fontWeight: '600', }, + contentAttrs: { + flexDirection: 'row', + justifyContent: 'flex-end', + alignItems: 'center', + gap: spacing.md, + flexWrap: 'wrap', + }, + contentAttrText: { + fontSize: fontSizes.sm, + color: colors.text.secondary, + }, }); } @@ -496,7 +512,7 @@ export function TradeDetailScreen({ tradeId }: TradeDetailScreenProps) { {item.price != null ? ( - 价格:¥{item.price % 1 === 0 ? item.price.toFixed(0) : item.price.toFixed(2)} + 价格:¥{item.price % 1 === 0 ? item.price.toFixed(0) : item.price.toFixed(2)} ) : ( 价格:面议 @@ -509,41 +525,12 @@ export function TradeDetailScreen({ tradeId }: TradeDetailScreenProps) { {/* 标题 */} {item.title} - {item.condition && item.trade_type === 'sell' && ( - - - - {TRADE_CONDITION_MAP[item.condition as keyof typeof TRADE_CONDITION_MAP] || item.condition} - - - - )} - - - {/* 商品属性 */} - - - 品牌 - {item.brand || '其他'} - - - 成色 - - {TRADE_CONDITION_MAP[item.condition as keyof typeof TRADE_CONDITION_MAP] || item.condition || '未知'} - - - - 功能状态 - {item.function_status || '正常使用'} - {/* 商品描述 */} {item.content && ( {item.content} )} - - {/* 图片放在文字下方 */} @@ -555,11 +542,23 @@ export function TradeDetailScreen({ tradeId }: TradeDetailScreenProps) { source={{ uri: img.url || img.preview_url_large || img.preview_url || '' }} style={styles.image} /> - ))} )} + + {/* 内容区右下角属性文字(仅出售商品显示) */} + {item.trade_type === 'sell' && ( + + + 品牌:{item.brand || '其他'} + + 成色:{TRADE_CONDITION_MAP[item.condition as keyof typeof TRADE_CONDITION_MAP] || item.condition || '未知'} + + 功能状态:{item.function_status || '正常使用'} + + + )} {/* 底部操作栏 */}