feat: mention

This commit is contained in:
gosangam
2026-06-10 16:29:44 +05:30
parent 482a845f37
commit 909ae67320
10 changed files with 628 additions and 66 deletions
+43 -16
View File
@@ -29,15 +29,17 @@
import { useEffect, useRef, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { ImageIcon, Repeat2 } from "lucide-react";
import { AtSign, ImageIcon, Repeat2 } from "lucide-react";
import { cn } from "@/lib/utils";
import type { Post, PostImage } from "@/lib/social";
import { displaySourceLabel } from "@/lib/source-reference";
import { useMediaQuery } from "@/components/selection-toolbar/shared";
import { useAuth } from "@/components/auth/auth-provider";
import { postSourceHref, quoteCardBgStyle } from "./post-card-shared";
import { PostActionsFooter } from "./post-actions-footer";
import { PostCardMenu } from "./post-card-menu";
import { UpdateBackgroundModal } from "./update-background-modal";
import { MentionsDrawer } from "./mentions-drawer";
export function PostScrollCard({
post,
@@ -52,23 +54,40 @@ export function PostScrollCard({
const hasImages = images.length > 0;
const sourceHref = postSourceHref(post);
const isMobile = useMediaQuery("(max-width: 767px)");
const { user } = useAuth();
const isAuthor = !!user && user.id === post.user_id;
const [bgModal, setBgModal] = useState(false);
const [expanded, setExpanded] = useState(false);
const [mentionsOpen, setMentionsOpen] = useState(false);
// Live mention count — seeded from the hydrated post, adjusted when the
// author edits tags in the drawer, so the icon appears/disappears in place.
const [mentionCount, setMentionCount] = useState(post.mentions_count ?? 0);
// Update Background stays as a media-overlay button — it's context-
// specific to the visible card surface and reads more naturally
// positioned over the image itself. Delete has moved into the
// header's three-dot menu (PostCardMenu) where Block / Report also
// live, so the overlay is now Update-Background-only.
const ownerCluster = onUpdated ? (
<div className="absolute top-3 right-3 z-10">
<OwnerButton
label="Update background"
onClick={() => setBgModal(true)}
icon={<ImageIcon className="size-4" />}
/>
</div>
) : null;
// The author always gets the mentions entry point (to add/remove); everyone
// else sees it only when the post actually tags someone.
const showMentions = mentionCount > 0 || isAuthor;
// Top-right media overlay: a Mentions icon and the owner-only
// Update-background button. Delete lives in the header menu.
const topRight =
showMentions || onUpdated ? (
<div className="absolute top-3 right-3 z-10 flex items-center gap-2">
{showMentions ? (
<OwnerButton
label="See who's mentioned"
onClick={() => setMentionsOpen(true)}
icon={<AtSign className="size-4" />}
/>
) : null}
{onUpdated ? (
<OwnerButton
label="Update background"
onClick={() => setBgModal(true)}
icon={<ImageIcon className="size-4" />}
/>
) : null}
</div>
) : null;
return (
<article
@@ -125,7 +144,7 @@ export function PostScrollCard({
) : (
<QuotePanel post={post} />
)}
{ownerCluster}
{topRight}
</div>
{/* Caption + citation — reference sits directly under the media
@@ -162,6 +181,14 @@ export function PostScrollCard({
onUpdated={onUpdated}
/>
) : null}
<MentionsDrawer
open={mentionsOpen}
postId={post.id}
authorId={post.user_id}
onClose={() => setMentionsOpen(false)}
onCountChange={(d) => setMentionCount((c) => Math.max(0, c + d))}
/>
</article>
);
}