feat: share post to other apps

This commit is contained in:
gosangam
2026-05-31 08:04:46 +05:30
parent 03b8f85e06
commit 336f478f8b
13 changed files with 1290 additions and 82 deletions
+74
View File
@@ -23,6 +23,8 @@ import {
ogForLetter,
ogForMagazine,
ogForOtherDocument,
ogForPost,
ogForProfile,
ogForTranscription,
ogForVerse,
} from "@/lib/og";
@@ -115,6 +117,10 @@ export async function buildShareOgMeta(fullPath: string): Promise<Metadata> {
return parts.length >= 3
? await ogForOtherDocPath(parts[1], parts[2], sp)
: ogDefault();
case "u":
// /u/<handle> → profile share
// /u/<handle>/posts#post-<id> → post share (post id in u.hash)
return await ogForProfilePath(parts, u.hash);
default:
return ogWithFallbackQuote("Prabhupāda Says", sp);
}
@@ -365,6 +371,74 @@ async function ogForOtherDocPath(
// Fallback
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Profile + post share dispatch
// ---------------------------------------------------------------------------
type PublicProfileForOg = {
handle: string;
name: string;
post_count?: number;
};
type PostForOg = {
id: string;
caption: string;
source_title?: string | null;
author_name?: string | null;
author_handle?: string | null;
};
/**
* Resolve `/u/<handle>` and `/u/<handle>/posts#post-<id>` share targets
* to the correct OG card. The hash carries the post id when the share
* is a single-post link (built by SharePostSheet); without a hash we
* fall back to a profile card for the handle.
*/
async function ogForProfilePath(
parts: string[],
hash: string,
): Promise<Metadata> {
if (parts.length < 2) return ogDefault();
const handle = parts[1];
// Post share: /u/<handle>/posts with `#post-<id>` fragment.
if (parts.length >= 3 && parts[2] === "posts") {
const m = hash.match(/^#post-(.+)$/);
if (m) {
const postID = m[1];
try {
const post = await bff<PostForOg>(
`/posts/${encodeURIComponent(postID)}`,
{ revalidate: 60 },
);
if (post) return ogForPost(post);
} catch {
// fall through to profile-level card
}
}
// No post id → treat as a feed share for the profile.
}
// Profile share: /u/<handle>
try {
const profile = await bff<PublicProfileForOg>(
`/u/${encodeURIComponent(handle)}`,
{ revalidate: 60 },
);
if (profile) {
return ogForProfile({
handle: profile.handle,
name: profile.name,
postCount: profile.post_count,
});
}
} catch {
// fall through
}
return ogDefault();
}
function ogWithFallbackQuote(
title: string,
sp: URLSearchParams,