feat(comments) : show heart giver profiles on comments and notifications

This commit is contained in:
2026-10-13 00:45:02 +07:00 Unverified
parent f8ef86cb5e
commit d1dff1a763
8 changed files with 135 additions and 23 deletions
+20 -19
View File
@@ -24,7 +24,7 @@ import {
Trash2Icon,
} from "lucide-react";
import { toast } from "sonner";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Avatar, AvatarBadge, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
@@ -377,6 +377,19 @@ export function CommentCard({
likes: item.likes,
hearted: item.hearted,
};
const heartedBy = item.heartedBy ?? (viewer?.admin && !item.hearted ? viewer : null);
const heartLabel = `${heartedBy?.name || "ผู้ดูแล"} ถูกใจความคิดเห็นนี้`;
const heartAvatar = (
<SimpleTooltip text={heartLabel}>
<Avatar size="sm" aria-label={heartLabel}>
<AvatarImage src={heartedBy?.image ?? undefined} alt="" />
<AvatarFallback>{heartedBy?.name?.slice(0, 2) || "ผู"}</AvatarFallback>
<AvatarBadge className="-right-0.5 -bottom-0.5 bg-transparent text-destructive ring-0 group-data-[size=sm]/avatar:size-3.5 group-data-[size=sm]/avatar:[&>svg]:block [&>svg]:size-2.5!">
<HeartIcon fill="currentColor" />
</AvatarBadge>
</Avatar>
</SimpleTooltip>
);
const reactionQueue = useRef<Promise<void>>(Promise.resolve());
const reactionSequence = useRef(0);
const queuedReactions = useRef(0);
@@ -759,35 +772,23 @@ export function CommentCard({
)}
{viewer?.admin ? (
<Button
variant={optimistic.hearted ? "secondary" : "ghost"}
size="sm"
variant="ghost"
size="icon"
className="rounded-full"
aria-label={optimistic.hearted ? "ยกเลิกหัวใจจากผู้ดูแล" : "ให้หัวใจจากผู้ดูแล"}
aria-pressed={optimistic.hearted}
disabled={pending || !item.canInteract}
onClick={() =>
void mutate("heart", !desired.current.hearted)
}
>
<HeartIcon
data-icon="inline-start"
className={cn(
optimistic.hearted && "text-destructive",
)}
fill={optimistic.hearted ? "currentColor" : "none"}
/>
{optimistic.hearted ? "ผู้ดูแลถูกใจ" : null}
{optimistic.hearted ? heartAvatar : <HeartIcon />}
</Button>
) : (
optimistic.hearted &&
!item.deleted &&
!item.hidden && (
<Badge variant="secondary">
<HeartIcon
data-icon="inline-start"
className="text-destructive"
fill="currentColor"
/>
{"ผู้ดูแลถูกใจ"}
</Badge>
heartAvatar
)
)}
</div>