fix: og image fix for collections
This commit is contained in:
@@ -152,29 +152,60 @@ export function PostCardMenu({
|
||||
// Copy the post's caption + source citation + a (short) link to the post —
|
||||
// the same payload the share sheet / footer produce. Available to every
|
||||
// viewer.
|
||||
async function copyCaption() {
|
||||
setOpen(false);
|
||||
try {
|
||||
const origin = window.location.origin;
|
||||
let url = "";
|
||||
if (authorHandle) {
|
||||
const longPath = `/u/${encodeURIComponent(authorHandle)}/posts#post-${post.id}`;
|
||||
const code = await createShortLink(longPath);
|
||||
url = code
|
||||
? new URL(`/share/${code}`, origin).toString()
|
||||
: new URL(longPath, origin).toString();
|
||||
}
|
||||
const ref = structuredReferenceForPost(post.source_url, post.source_title);
|
||||
const lines: string[] = [];
|
||||
if (post.caption) lines.push(`“${post.caption}”`, "");
|
||||
lines.push("Source:", ref.title);
|
||||
if (ref.detail) lines.push(ref.detail);
|
||||
if (url) lines.push(url);
|
||||
await navigator.clipboard.writeText(lines.join("\n"));
|
||||
toast.success("Caption copied");
|
||||
} catch {
|
||||
toast.error("Could not copy");
|
||||
// Build the copy payload — caption + citation + a short link to the post.
|
||||
// The short link is a network round-trip, so we must NOT await it before
|
||||
// touching the clipboard or we lose the click's transient user activation
|
||||
// (the write then fails on the first click and only lands on the second,
|
||||
// once the link is cached). See `useCopyFeedback` for the same fix.
|
||||
async function buildCaptionText(): Promise<string> {
|
||||
const origin = window.location.origin;
|
||||
let url = "";
|
||||
if (authorHandle) {
|
||||
const longPath = `/u/${encodeURIComponent(authorHandle)}/posts#post-${post.id}`;
|
||||
const code = await createShortLink(longPath);
|
||||
url = code
|
||||
? new URL(`/share/${code}`, origin).toString()
|
||||
: new URL(longPath, origin).toString();
|
||||
}
|
||||
const ref = structuredReferenceForPost(post.source_url, post.source_title);
|
||||
const lines: string[] = [];
|
||||
if (post.caption) lines.push(`“${post.caption}”`, "");
|
||||
lines.push("Source:", ref.title);
|
||||
if (ref.detail) lines.push(ref.detail);
|
||||
if (url) lines.push(url);
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
function copyCaption() {
|
||||
setOpen(false);
|
||||
// Hand the clipboard a *Promise* of the text via ClipboardItem so the
|
||||
// browser keeps the gesture alive while the short link resolves — one
|
||||
// click copies cleanly.
|
||||
if (typeof ClipboardItem !== "undefined" && navigator.clipboard?.write) {
|
||||
try {
|
||||
const item = new ClipboardItem({
|
||||
"text/plain": buildCaptionText().then(
|
||||
(s) => new Blob([s], { type: "text/plain" }),
|
||||
),
|
||||
});
|
||||
navigator.clipboard.write([item]).then(
|
||||
() => toast.success("Caption copied"),
|
||||
() => toast.error("Could not copy"),
|
||||
);
|
||||
return;
|
||||
} catch {
|
||||
// ClipboardItem-with-promise unsupported → fall through to the
|
||||
// await + writeText path below.
|
||||
}
|
||||
}
|
||||
void buildCaptionText().then(async (text) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
toast.success("Caption copied");
|
||||
} catch {
|
||||
toast.error("Could not copy");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Build the items list AFTER all hooks have run so a conditional
|
||||
|
||||
Reference in New Issue
Block a user