- Migrate all navigation calls from magic strings to centralized href helpers - Extract inline device registration logic into useRegisterPushDevice hook - Remove unused terms and privacy policy routes from profile stack - Add hrefTradeDetail helper for trade detail navigation - Restore routePayloadCache.stashSystemMessage for group request/invite handling - Change desktop shell tab navigation from replace to push
125 lines
3.5 KiB
TypeScript
125 lines
3.5 KiB
TypeScript
import React, { useCallback } from 'react';
|
|
import { View, TouchableOpacity, StyleSheet, ActivityIndicator } from 'react-native';
|
|
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
|
import { useRouter } from 'expo-router';
|
|
|
|
import Text from '../common/Text';
|
|
import { useAppColors, spacing, borderRadius } from '../../theme';
|
|
import type { PostRefSegmentData } from '../../types';
|
|
import * as hrefs from '../../navigation/hrefs';
|
|
|
|
interface PostRefCardProps {
|
|
data: PostRefSegmentData;
|
|
compact?: boolean;
|
|
onPress?: (postId: string) => void;
|
|
}
|
|
|
|
const PostRefCard: React.FC<PostRefCardProps> = ({ data, compact = false, onPress }) => {
|
|
const colors = useAppColors();
|
|
const router = useRouter();
|
|
|
|
const handlePress = useCallback(() => {
|
|
if (onPress) {
|
|
onPress(data.post_id);
|
|
} else {
|
|
router.push(hrefs.hrefPostDetail(data.post_id));
|
|
}
|
|
}, [data.post_id, onPress, router]);
|
|
|
|
const isDeleted = data.status === 'deleted';
|
|
const isHidden = data.status === 'hidden';
|
|
const isUnavailable = isDeleted || isHidden || !data.accessible;
|
|
const authorName = data.author?.nickname || '';
|
|
|
|
if (isUnavailable) {
|
|
return (
|
|
<View
|
|
style={[
|
|
styles.container,
|
|
{ backgroundColor: colors.background.default, borderColor: colors.divider },
|
|
compact && styles.containerCompact,
|
|
]}
|
|
>
|
|
<MaterialCommunityIcons name="link-off" size={16} color={colors.text.hint} />
|
|
<Text style={[styles.unavailableText, { color: colors.text.hint }]} numberOfLines={1}>
|
|
{isDeleted ? '该帖子已删除' : isHidden ? '该帖子不可见' : '请登录后查看'}
|
|
</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
style={[
|
|
styles.container,
|
|
{ backgroundColor: colors.background.default, borderColor: colors.primary.light },
|
|
compact && styles.containerCompact,
|
|
]}
|
|
onPress={handlePress}
|
|
activeOpacity={0.7}
|
|
>
|
|
<View style={[styles.iconWrap, { backgroundColor: colors.primary.light }]}>
|
|
<MaterialCommunityIcons name="file-document-outline" size={14} color={colors.primary.main} />
|
|
</View>
|
|
<View style={styles.contentWrap}>
|
|
<Text
|
|
style={[styles.title, { color: colors.text.primary }]}
|
|
numberOfLines={compact ? 1 : 2}
|
|
>
|
|
{data.title || '帖子'}
|
|
</Text>
|
|
{authorName ? (
|
|
<Text style={[styles.author, { color: colors.text.secondary }]} numberOfLines={1}>
|
|
@{authorName}
|
|
</Text>
|
|
) : null}
|
|
</View>
|
|
<MaterialCommunityIcons name="chevron-right" size={16} color={colors.text.hint} />
|
|
</TouchableOpacity>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
borderWidth: 1,
|
|
borderRadius: borderRadius.md,
|
|
paddingVertical: spacing.sm,
|
|
paddingHorizontal: spacing.md,
|
|
marginTop: spacing.xs,
|
|
marginBottom: spacing.xs,
|
|
},
|
|
containerCompact: {
|
|
paddingVertical: spacing.xs,
|
|
paddingHorizontal: spacing.sm,
|
|
},
|
|
iconWrap: {
|
|
width: 24,
|
|
height: 24,
|
|
borderRadius: 4,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
marginRight: spacing.sm,
|
|
},
|
|
contentWrap: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
},
|
|
title: {
|
|
fontSize: 13,
|
|
fontWeight: '500',
|
|
lineHeight: 18,
|
|
},
|
|
author: {
|
|
fontSize: 11,
|
|
lineHeight: 14,
|
|
marginTop: 1,
|
|
},
|
|
unavailableText: {
|
|
fontSize: 13,
|
|
marginLeft: spacing.sm,
|
|
},
|
|
});
|
|
|
|
export default PostRefCard; |