clean up the share button(s)

This commit is contained in:
Václav Pavlín 2025-09-10 13:21:12 +02:00
parent 244119bb05
commit df2efac6c3
No known key found for this signature in database
GPG Key ID: B378FB31BB6D89A5
6 changed files with 124 additions and 44 deletions

View File

@ -27,6 +27,7 @@ import { ModerationToggle } from './ui/moderation-toggle';
import { sortCells, SortOption } from '@/lib/utils/sorting';
import { Cell } from '@/types/forum';
import { usePending } from '@/hooks/usePending';
import { ShareButton } from './ui/ShareButton';
// Empty State Component
const EmptyState: React.FC<{ canCreateCell: boolean }> = ({
@ -125,6 +126,11 @@ const CellItem: React.FC<{ cell: Cell }> = ({ cell }) => {
{cell.activeMemberCount || 0} members
</span>
</div>
<ShareButton
size='sm'
url={`${window.location.origin}/cell/${cell.id}`}
title={cell.name}
/>
</div>
</div>
</div>

View File

@ -18,6 +18,7 @@ import {
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { ShareButton } from '@/components/ui/ShareButton';
interface CommentCardProps {
comment: Comment;
@ -126,13 +127,20 @@ const CommentCard: React.FC<CommentCardProps> = ({
</span>
<PendingBadge id={comment.id} />
</div>
<BookmarkButton
isBookmarked={isBookmarked}
loading={bookmarkLoading}
onClick={handleBookmark}
size="sm"
variant="ghost"
/>
<div className="flex items-center gap-2">
<ShareButton
size='sm'
url={`${window.location.origin}/post/${postId}#comment-${comment.id}`}
title={comment.content.substring(0, 50) + (comment.content.length > 50 ? '...' : '')}
/>
<BookmarkButton
isBookmarked={isBookmarked}
loading={bookmarkLoading}
onClick={handleBookmark}
size="sm"
variant="ghost"
/>
</div>
</div>
<p className="text-sm break-words mb-2">

View File

@ -15,7 +15,7 @@ import { AuthorDisplay } from '@/components/ui/author-display';
import { BookmarkButton } from '@/components/ui/bookmark-button';
import { LinkRenderer } from '@/components/ui/link-renderer';
import { usePending, usePendingVote } from '@/hooks/usePending';
import { useToast } from '@/components/ui/use-toast';
import { ShareButton } from '@/components/ui/ShareButton';
interface PostCardProps {
post: Post;
@ -32,7 +32,6 @@ const PostCard: React.FC<PostCardProps> = ({ post, commentCount = 0 }) => {
loading: bookmarkLoading,
toggleBookmark,
} = usePostBookmark(post, post.cellId);
const { toast } = useToast();
// ✅ Get pre-computed cell data
const cell = cellsWithStats.find(c => c.id === post.cellId);
@ -71,33 +70,6 @@ const PostCard: React.FC<PostCardProps> = ({ post, commentCount = 0 }) => {
await toggleBookmark();
};
const handleShare = async (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
const postUrl = `${window.location.origin}/post/${post.id}`;
try {
await navigator.clipboard.writeText(postUrl);
toast({
title: 'Link copied!',
description: 'Post link has been copied to your clipboard.',
});
} catch {
// Fallback for older browsers
const textArea = document.createElement('textarea');
textArea.value = postUrl;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
toast({
title: 'Link copied!',
description: 'Post link has been copied to your clipboard.',
});
}
};
return (
<div className="thread-card mb-2">
@ -207,14 +179,11 @@ const PostCard: React.FC<PostCardProps> = ({ post, commentCount = 0 }) => {
syncing
</span>
)}
<button
onClick={handleShare}
className="hover:text-cyber-accent transition-colors flex items-center gap-1"
title="Copy link"
>
<Clipboard size={14} />
Share
</button>
<ShareButton
size='sm'
url={`${window.location.origin}/post/${post.id}`}
title={post.title}
/>
</div>
<BookmarkButton
isBookmarked={isBookmarked}

View File

@ -27,6 +27,7 @@ import { BookmarkButton } from './ui/bookmark-button';
import { LinkRenderer } from './ui/link-renderer';
import CommentCard from './CommentCard';
import { usePending, usePendingVote } from '@/hooks/usePending';
import { ShareButton } from './ui/ShareButton';
const PostDetail = () => {
const { postId } = useParams<{ postId: string }>();
@ -243,6 +244,11 @@ const PostDetail = () => {
variant="ghost"
showText={true}
/>
<ShareButton
size='lg'
url={`${window.location.origin}/post/${post.id}`}
title={post.title}
/>
</div>
<p className="text-sm whitespace-pre-wrap break-words">
<LinkRenderer text={post.content} />

View File

@ -14,6 +14,7 @@ import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Skeleton } from '@/components/ui/skeleton';
import { LinkRenderer } from '@/components/ui/link-renderer';
import { ShareButton } from '@/components/ui/ShareButton';
import {
ArrowLeft,
MessageSquare,
@ -324,6 +325,15 @@ const PostList = () => {
className="text-xs"
showBadge={false}
/>
<ShareButton
url={`${window.location.origin}/post/${post.id}`}
title={post.title}
description={post.content}
size="sm"
variant="ghost"
className="text-cyber-neutral"
showText={false}
/>
</div>
</Link>
{canModerate(cell.id) && !post.moderated && (

View File

@ -0,0 +1,81 @@
import { Button } from '@/components/ui/button';
import { Share2 } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useToast } from '../ui/use-toast';
interface ShareButtonProps {
url: string;
title: string;
description?: string;
size?: 'sm' | 'lg';
variant?: 'default' | 'ghost' | 'outline';
className?: string;
showText?: boolean;
}
export function ShareButton({
url,
title,
description = 'Check out this post',
size = 'sm',
variant = 'ghost',
className,
showText = false,
}: ShareButtonProps) {
const { toast } = useToast();
const sizeClasses = {
sm: 'h-8 w-10',
lg: 'h-10 whitespace-nowrap px-4',
};
const iconSize = {
sm: 14,
lg: 18,
};
const handleShare = async (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
try {
await navigator.clipboard.writeText(url);
toast({
title: 'Link copied!',
description: 'Link has been copied to your clipboard.',
});
} catch {
// Fallback for older browsers
const textArea = document.createElement('textarea');
textArea.value = url;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
toast({
title: 'Link copied!',
description: 'Link has been copied to your clipboard.',
});
}
};
return (
<Button
variant={variant}
size={size}
onClick={handleShare}
className={cn(
sizeClasses[size],
'transition-colors duration-200 text-cyber-neutral hover:text-cyber-light',
className
)}
title="Copy link"
>
<Share2 size={iconSize[size]} />
{showText && (
<span className="ml-2 text-xs">Share</span>
)}
</Button>
);
}