fix: chat accepts posts
This commit is contained in:
@@ -18,6 +18,7 @@ import { LinkPreviewCard } from "@/components/chat/link-preview-card";
|
||||
import { MediaGrid } from "@/components/chat/media-grid";
|
||||
import { MediaLightbox } from "@/components/chat/media-lightbox";
|
||||
import { QuoteCard } from "@/components/chat/quote-card";
|
||||
import { SharedPostCard } from "@/components/chat/shared-post-card";
|
||||
import { attachmentUrl, type Attachment } from "@/lib/chat";
|
||||
|
||||
function humanSize(bytes?: number | null): string {
|
||||
@@ -58,6 +59,9 @@ export function MessageAttachments({
|
||||
|
||||
{rest.map((a) => {
|
||||
switch (a.kind) {
|
||||
case "entity":
|
||||
return <SharedPostCard key={a.id} attachment={a} />;
|
||||
|
||||
case "quote":
|
||||
return <QuoteCard key={a.id} attachment={a} />;
|
||||
|
||||
|
||||
@@ -37,12 +37,16 @@ type SendState = "idle" | "sending" | "sent";
|
||||
export function ShareToChatDialog({
|
||||
body = "",
|
||||
quote,
|
||||
entity,
|
||||
onClose,
|
||||
}: {
|
||||
/** Plain message text. Empty when sending a quote on its own. */
|
||||
body?: string;
|
||||
/** A passage from the library, sent as a tappable quotation. */
|
||||
quote?: QuotePayload;
|
||||
/** A post, sent as a card. Only the reference travels — the BFF resolves
|
||||
* the contents and re-checks visibility for each viewer. */
|
||||
entity?: { type: "post"; id: string };
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const { user } = useAuth();
|
||||
@@ -111,7 +115,7 @@ export function ShareToChatDialog({
|
||||
mark(handle, "sending");
|
||||
try {
|
||||
const id = conversationId ?? (await chat.openDM(handle)).id;
|
||||
await chat.send(id, body, { quote });
|
||||
await chat.send(id, body, { quote, entity });
|
||||
mark(handle, "sent");
|
||||
} catch {
|
||||
mark(handle, "idle");
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* A post shared into a chat, rendered as a card with its author.
|
||||
*
|
||||
* The contents are resolved by the BFF on every read, per viewer — never from
|
||||
* a snapshot frozen at send time. So a post that has since been deleted or
|
||||
* hidden arrives as `entity_unavailable` and renders as a tombstone rather
|
||||
* than quietly showing content the reader is no longer allowed to see.
|
||||
*/
|
||||
|
||||
import Link from "next/link";
|
||||
import { ImageOff } from "lucide-react";
|
||||
import { UserAvatar } from "@/components/ui/user-avatar";
|
||||
import type { Attachment } from "@/lib/chat";
|
||||
|
||||
export function SharedPostCard({ attachment }: { attachment: Attachment }) {
|
||||
const post = attachment.entity;
|
||||
|
||||
if (!post || attachment.entity_unavailable) {
|
||||
return (
|
||||
<div className="mt-1 flex items-center gap-2 rounded-lg border border-border bg-muted/30 px-3 py-2.5">
|
||||
<ImageOff className="size-4 shrink-0 text-muted-foreground" aria-hidden />
|
||||
<span className="text-sm text-muted-foreground">
|
||||
This post is no longer available
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={`/u/${encodeURIComponent(post.author_handle)}/posts#post-${post.id}`}
|
||||
className="mt-1 block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:bg-muted/40"
|
||||
>
|
||||
<span className="flex items-center gap-2 px-3 py-2">
|
||||
<UserAvatar
|
||||
src={post.author_avatar_url ?? null}
|
||||
name={post.author_name}
|
||||
className="size-6 shrink-0"
|
||||
/>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate text-xs font-medium text-foreground">
|
||||
{post.author_name}
|
||||
</span>
|
||||
<span className="block truncate text-[11px] text-muted-foreground">
|
||||
@{post.author_handle}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{post.image_url && (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={post.image_url}
|
||||
alt=""
|
||||
loading="lazy"
|
||||
className="aspect-square w-full object-cover"
|
||||
/>
|
||||
)}
|
||||
|
||||
{post.caption && (
|
||||
<span className="block px-3 py-2 text-sm leading-relaxed text-foreground line-clamp-3">
|
||||
{post.caption}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{post.source_title && (
|
||||
<span className="block truncate px-3 pb-2 text-xs text-muted-foreground">
|
||||
{post.source_title}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user