54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
/**
|
|
* Builds the shareable text for a post — the caption, its source reference,
|
|
* and a link.
|
|
*
|
|
* Extracted so the native share sheet and "send to a chat" quote a post
|
|
* identically. They differ only in where the text ends up, and two copies of
|
|
* this would drift the moment either format changed.
|
|
*/
|
|
|
|
import { createShortLink } from "@/lib/share";
|
|
import { structuredReferenceForPost } from "@/lib/source-reference";
|
|
import type { Post } from "@/lib/social";
|
|
|
|
export type PostShareText = {
|
|
/** Short link when the shortener answered, canonical URL otherwise. */
|
|
url: string;
|
|
/** Source reference on one line, for a native share sheet's title slot. */
|
|
title: string;
|
|
/** Caption, source reference and link — the body of the share. */
|
|
text: string;
|
|
};
|
|
|
|
/**
|
|
* `viewerHandle` covers the case where the BFF's create response omits
|
|
* author_handle: the poster IS the signed-in user right after posting.
|
|
* Returns null when neither yields a handle, since there is no post URL
|
|
* without one.
|
|
*/
|
|
export async function buildPostShareText(
|
|
post: Post,
|
|
viewerHandle: string | undefined,
|
|
): Promise<PostShareText | null> {
|
|
const handle = post.author_handle ?? viewerHandle ?? "";
|
|
if (!handle) return null;
|
|
|
|
const longPath = `/u/${encodeURIComponent(handle)}/posts#post-${post.id}`;
|
|
const code = await createShortLink(longPath);
|
|
const origin = window.location.origin;
|
|
const url = code
|
|
? new URL(`/share/${code}`, origin).toString()
|
|
: new URL(longPath, origin).toString();
|
|
|
|
const ref = structuredReferenceForPost(post.source_url, post.source_title);
|
|
const lines = [`“${post.caption}”`, "", "Source:", ref.title];
|
|
if (ref.detail) lines.push(ref.detail);
|
|
lines.push(url);
|
|
|
|
return {
|
|
url,
|
|
title: ref.detail ? `${ref.title} — ${ref.detail}` : ref.title,
|
|
text: lines.join("\n"),
|
|
};
|
|
}
|