PC端的部分适配
This commit is contained in:
@@ -59,6 +59,9 @@ const SearchBar: React.FC<SearchBarProps> = ({
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
autoFocus={autoFocus}
|
||||
// 确保光标可见
|
||||
cursorColor={colors.primary.main}
|
||||
selectionColor={`${colors.primary.main}40`}
|
||||
/>
|
||||
{value.length > 0 && (
|
||||
<TouchableOpacity
|
||||
@@ -87,18 +90,22 @@ const styles = StyleSheet.create({
|
||||
height: 46,
|
||||
borderWidth: 1,
|
||||
borderColor: '#E7E7E7',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.09,
|
||||
shadowRadius: 6,
|
||||
elevation: 2,
|
||||
// 减少常态阴影,避免看起来像"黑框"
|
||||
shadowColor: 'transparent',
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: 0,
|
||||
shadowRadius: 0,
|
||||
elevation: 0,
|
||||
},
|
||||
containerFocused: {
|
||||
borderColor: `${colors.primary.main}66`,
|
||||
shadowColor: colors.primary.main,
|
||||
shadowOpacity: 0.18,
|
||||
shadowRadius: 10,
|
||||
elevation: 4,
|
||||
// 焦点时使用更柔和的边框颜色
|
||||
borderColor: colors.primary.main,
|
||||
// 不添加额外的阴影,保持简洁
|
||||
shadowColor: 'transparent',
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: 0,
|
||||
shadowRadius: 0,
|
||||
elevation: 0,
|
||||
},
|
||||
searchIconWrap: {
|
||||
width: 30,
|
||||
|
||||
@@ -13,6 +13,7 @@ import { colors, spacing, borderRadius } from '../../theme';
|
||||
import { SystemMessageResponse, SystemMessageType } from '../../types/dto';
|
||||
import Text from '../common/Text';
|
||||
import Avatar from '../common/Avatar';
|
||||
import { useResponsive, useResponsiveValue } from '../../hooks/useResponsive';
|
||||
|
||||
interface SystemMessageItemProps {
|
||||
message: SystemMessageResponse;
|
||||
@@ -164,6 +165,14 @@ const SystemMessageItem: React.FC<SystemMessageItemProps> = ({
|
||||
onRequestAction,
|
||||
requestActionLoading = false,
|
||||
}) => {
|
||||
// 响应式适配
|
||||
const { isWideScreen, isDesktop } = useResponsive();
|
||||
const containerPadding = useResponsiveValue({ xs: spacing.md, lg: spacing.lg, xl: spacing.xl });
|
||||
const avatarSize = useResponsiveValue({ xs: 40, lg: 48, xl: 52 });
|
||||
const iconSize = useResponsiveValue({ xs: 20, lg: 22, xl: 24 });
|
||||
const contentFontSize = useResponsiveValue({ xs: 14, lg: 15, xl: 16 });
|
||||
const titleFontSize = useResponsiveValue({ xs: 14, lg: 15, xl: 16 });
|
||||
const timeFontSize = useResponsiveValue({ xs: 12, lg: 13, xl: 14 });
|
||||
// 格式化时间
|
||||
const formatTime = (dateString: string): string => {
|
||||
try {
|
||||
@@ -189,6 +198,89 @@ const SystemMessageItem: React.FC<SystemMessageItemProps> = ({
|
||||
requestStatus === 'pending' &&
|
||||
!!onRequestAction;
|
||||
|
||||
const styles = React.useMemo(() => StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
padding: containerPadding,
|
||||
backgroundColor: colors.background.paper,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.divider,
|
||||
},
|
||||
iconContainer: {
|
||||
marginRight: isWideScreen ? spacing.lg : spacing.md,
|
||||
},
|
||||
iconWrapper: {
|
||||
width: avatarSize,
|
||||
height: avatarSize,
|
||||
borderRadius: avatarSize / 2,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
titleRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: spacing.xs,
|
||||
},
|
||||
title: {
|
||||
fontWeight: '600',
|
||||
flex: 1,
|
||||
marginRight: spacing.sm,
|
||||
fontSize: titleFontSize,
|
||||
},
|
||||
time: {
|
||||
fontSize: timeFontSize,
|
||||
},
|
||||
messageContent: {
|
||||
lineHeight: isWideScreen ? 22 : 18,
|
||||
fontSize: contentFontSize,
|
||||
},
|
||||
extraInfo: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginTop: spacing.xs,
|
||||
backgroundColor: colors.background.default,
|
||||
paddingHorizontal: isWideScreen ? spacing.md : spacing.sm,
|
||||
paddingVertical: spacing.xs,
|
||||
borderRadius: borderRadius.sm,
|
||||
alignSelf: 'flex-start',
|
||||
},
|
||||
extraText: {
|
||||
marginLeft: spacing.xs,
|
||||
flex: 1,
|
||||
},
|
||||
actionsRow: {
|
||||
flexDirection: 'row',
|
||||
marginTop: spacing.sm,
|
||||
},
|
||||
actionBtn: {
|
||||
paddingVertical: isWideScreen ? spacing.sm : spacing.xs,
|
||||
paddingHorizontal: isWideScreen ? spacing.lg : spacing.md,
|
||||
borderRadius: borderRadius.sm,
|
||||
borderWidth: 1,
|
||||
marginRight: spacing.sm,
|
||||
},
|
||||
rejectBtn: {
|
||||
borderColor: colors.error.light,
|
||||
backgroundColor: colors.error.light + '18',
|
||||
},
|
||||
approveBtn: {
|
||||
borderColor: colors.success.light,
|
||||
backgroundColor: colors.success.light + '18',
|
||||
},
|
||||
arrowContainer: {
|
||||
marginLeft: spacing.sm,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 20,
|
||||
},
|
||||
}), [containerPadding, isWideScreen, avatarSize, titleFontSize, timeFontSize, contentFontSize]);
|
||||
|
||||
// 判断是否显示操作者头像
|
||||
const showOperatorAvatar = ['follow', 'like_post', 'like_comment', 'like_reply', 'favorite_post', 'comment', 'reply', 'mention', 'group_join_apply'].includes(
|
||||
message.system_type
|
||||
@@ -207,19 +299,19 @@ const SystemMessageItem: React.FC<SystemMessageItemProps> = ({
|
||||
{showGroupAvatar ? (
|
||||
<Avatar
|
||||
source={groupAvatar || ''}
|
||||
size={44}
|
||||
size={avatarSize}
|
||||
name={extra_data?.group_name || '群聊'}
|
||||
/>
|
||||
) : showOperatorAvatar ? (
|
||||
<Avatar
|
||||
source={operatorAvatar || ''}
|
||||
size={44}
|
||||
size={avatarSize}
|
||||
name={operatorName}
|
||||
onPress={onAvatarPress}
|
||||
/>
|
||||
) : (
|
||||
<View style={[styles.iconWrapper, { backgroundColor: bgColor }]}>
|
||||
<MaterialCommunityIcons name={icon} size={22} color={color} />
|
||||
<MaterialCommunityIcons name={icon} size={iconSize} color={color} />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
@@ -231,7 +323,7 @@ const SystemMessageItem: React.FC<SystemMessageItemProps> = ({
|
||||
<Text variant="body" style={styles.title} numberOfLines={1}>
|
||||
{title}
|
||||
</Text>
|
||||
<Text variant="caption" color={colors.text.secondary}>
|
||||
<Text variant="caption" color={colors.text.secondary} style={styles.time}>
|
||||
{formatTime(message.created_at)}
|
||||
</Text>
|
||||
</View>
|
||||
@@ -288,82 +380,4 @@ const SystemMessageItem: React.FC<SystemMessageItemProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
padding: spacing.lg,
|
||||
backgroundColor: colors.background.paper,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.divider,
|
||||
},
|
||||
iconContainer: {
|
||||
marginRight: spacing.md,
|
||||
},
|
||||
iconWrapper: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
borderRadius: 22,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
titleRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: spacing.xs,
|
||||
},
|
||||
title: {
|
||||
fontWeight: '600',
|
||||
flex: 1,
|
||||
marginRight: spacing.sm,
|
||||
},
|
||||
messageContent: {
|
||||
lineHeight: 18,
|
||||
},
|
||||
extraInfo: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginTop: spacing.xs,
|
||||
backgroundColor: colors.background.default,
|
||||
paddingHorizontal: spacing.sm,
|
||||
paddingVertical: spacing.xs,
|
||||
borderRadius: borderRadius.sm,
|
||||
alignSelf: 'flex-start',
|
||||
},
|
||||
extraText: {
|
||||
marginLeft: spacing.xs,
|
||||
flex: 1,
|
||||
},
|
||||
actionsRow: {
|
||||
flexDirection: 'row',
|
||||
marginTop: spacing.sm,
|
||||
},
|
||||
actionBtn: {
|
||||
paddingVertical: spacing.xs,
|
||||
paddingHorizontal: spacing.md,
|
||||
borderRadius: borderRadius.sm,
|
||||
borderWidth: 1,
|
||||
marginRight: spacing.sm,
|
||||
},
|
||||
rejectBtn: {
|
||||
borderColor: colors.error.light,
|
||||
backgroundColor: colors.error.light + '18',
|
||||
},
|
||||
approveBtn: {
|
||||
borderColor: colors.success.light,
|
||||
backgroundColor: colors.success.light + '18',
|
||||
},
|
||||
arrowContainer: {
|
||||
marginLeft: spacing.sm,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 20,
|
||||
},
|
||||
});
|
||||
|
||||
export default SystemMessageItem;
|
||||
|
||||
@@ -105,6 +105,9 @@ const Input: React.FC<InputProps> = ({
|
||||
autoCapitalize={autoCapitalize}
|
||||
keyboardType={keyboardType}
|
||||
autoCorrect={autoCorrect}
|
||||
// 确保光标可见
|
||||
cursorColor={colors.primary.main}
|
||||
selectionColor={`${colors.primary.main}40`}
|
||||
/>
|
||||
{rightIcon && (
|
||||
<TouchableOpacity
|
||||
@@ -143,6 +146,8 @@ const styles = StyleSheet.create({
|
||||
borderWidth: 1,
|
||||
borderRadius: borderRadius.md,
|
||||
paddingHorizontal: spacing.md,
|
||||
// 减少非焦点状态的边框明显度
|
||||
borderColor: colors.divider,
|
||||
},
|
||||
input: {
|
||||
flex: 1,
|
||||
|
||||
Reference in New Issue
Block a user