feat(ui): add ShareSheet component for multi-channel post sharing
Some checks failed
Frontend CI / ota-android (push) Successful in 10m39s
Frontend CI / build-and-push-web (push) Failing after 1m29s
Frontend CI / build-android-apk (push) Has been cancelled

Add ShareSheet component that provides native sharing options (WeChat, Moments, copy link, etc.) replacing the previous clipboard-only approach. Also change like icon from heart to thumb-up to better match the share functionality.
This commit is contained in:
lafay
2026-04-19 23:58:26 +08:00
parent 6910fdec70
commit b16759a147
8 changed files with 148 additions and 60 deletions

View File

@@ -280,10 +280,10 @@ function createPostCardStyles(colors: AppColors) {
marginLeft: 4,
},
activeActionText: {
color: colors.error.main,
color: colors.primary.main,
},
activeActionTextMerged: {
color: colors.error.main,
color: colors.primary.main,
fontSize: fontSizes.sm,
marginLeft: 4,
},
@@ -589,7 +589,7 @@ const PostCardInner: React.FC<PostCardProps> = (normalizedProps) => {
<Text style={styles.gridUsername} numberOfLines={1}>{author?.nickname || '匿名用户'}</Text>
</TouchableOpacity>
<View style={styles.gridLikeArea}>
<MaterialCommunityIcons name="heart-outline" size={14} color={colors.text.secondary} />
<MaterialCommunityIcons name="thumb-up-outline" size={14} color={colors.text.secondary} />
<Text style={styles.gridLikeCount}>{formatNumber(post.likes_count || 0)}</Text>
</View>
</View>
@@ -677,9 +677,9 @@ const PostCardInner: React.FC<PostCardProps> = (normalizedProps) => {
<View style={styles.actionButtons}>
<TouchableOpacity style={styles.actionBtn} onPress={handleLike}>
<MaterialCommunityIcons
name={post.is_liked ? 'heart' : 'heart-outline'}
name={post.is_liked ? 'thumb-up' : 'thumb-up-outline'}
size={18}
color={post.is_liked ? colors.error.main : colors.text.secondary}
color={post.is_liked ? colors.primary.main : colors.text.secondary}
/>
<Text style={post.is_liked ? styles.activeActionTextMerged : styles.actionText}>
{post.likes_count > 0 ? formatNumber(post.likes_count) : '赞'}

View File

@@ -0,0 +1,55 @@
import React, { useEffect, useMemo } from 'react';
import { Share as RNShare, Platform } from 'react-native';
export interface ShareSheetProps {
visible: boolean;
postUrl?: string;
postTitle?: string;
onClose: () => void;
onShareAction?: (actionKey: string) => void;
}
const ShareSheet: React.FC<ShareSheetProps> = ({
visible,
postUrl,
postTitle,
onClose,
onShareAction,
}) => {
const shareText = useMemo(() => {
const title = postTitle || '胡萝卜BBS帖子';
return `${title} ${postUrl || ''}`;
}, [postTitle, postUrl]);
useEffect(() => {
if (!visible) return;
const doShare = async () => {
try {
await RNShare.share(
{
message: shareText,
url: Platform.OS === 'ios' ? postUrl : undefined,
title: postTitle || '分享帖子',
},
{
subject: postTitle,
dialogTitle: '分享到',
}
);
onShareAction?.('system_share');
} catch {
// User cancelled
} finally {
onClose();
}
};
doShare();
}, [visible, shareText, postUrl, postTitle, onShareAction, onClose]);
return null;
};
export default ShareSheet;

View File

@@ -0,0 +1,2 @@
export { default } from './ShareSheet';
export type { ShareSheetProps } from './ShareSheet';

View File

@@ -23,3 +23,4 @@ export { default as VoteCard } from './VoteCard';
export { default as VoteEditor } from './VoteEditor';
export { default as VotePreview } from './VotePreview';
export { default as ReportDialog } from './ReportDialog';
export { default as ShareSheet } from './ShareSheet';