feat: add framer motion for audio player, handle og images for transcripts

This commit is contained in:
gosangam
2026-05-09 11:59:48 +05:30
parent 9eb2a06b50
commit 326ba090ca
10 changed files with 1187 additions and 11826 deletions
+35 -11
View File
@@ -7,7 +7,7 @@ import {
getTranscription,
getAdjacentTranscriptions,
} from "@/lib/transcriptions";
import { buildOgMeta } from "@/lib/og";
import { buildOgMeta, ogForTranscription, extractQuoteFromHl } from "@/lib/og";
import { PageHeader } from "@/components/page-header";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
@@ -18,25 +18,49 @@ import { PlayAudioButton } from "./play-audio-button";
export async function generateMetadata({
params,
searchParams,
}: {
params: Promise<{ slug: string }>;
searchParams: Promise<Record<string, string | string[] | undefined>>;
}): Promise<Metadata> {
const { slug } = await params;
const sp = await searchParams;
const t = await getTranscription(slug);
if (!t) return {};
const detail = [t.date, t.place].filter(Boolean).join(" · ");
return buildOgMeta({
title: t.name,
detail: detail || undefined,
quote:
t.content.length > 0
? t.content
.find((b) => b.speaker === "Prabhupāda" && b.text.length > 50)
?.text?.replace(/<[^>]+>/g, "")
.slice(0, 200)
: undefined,
// Build paragraphs from content blocks for hl matching
const paragraphs = t.content.map((b) => {
const speakerPrefix = b.speaker ? `${b.speaker}: ` : "";
return speakerPrefix + b.text.replace(/<[^>]+>/g, "");
});
const hlQuote = extractQuoteFromHl(sp, paragraphs);
if (hlQuote) {
return buildOgMeta({
title: t.name,
detail: detail || undefined,
quote: hlQuote,
});
}
// Fallback: find a good Prabhupāda quote from the content
const spQuote = t.content
.find((b) => b.speaker === "Prabhupāda" && b.text.length > 50)
?.text?.replace(/<[^>]+>/g, "")
.slice(0, 200);
if (spQuote) {
return buildOgMeta({
title: t.name,
detail: detail || undefined,
quote: spQuote,
});
}
return ogForTranscription(t.name, detail || undefined);
}
export default async function TranscriptionPage({
@@ -1,8 +1,12 @@
"use client";
import { useAudioPlayer, type AudioTrack } from "@/components/audio-player";
import {
useAudioPlayer,
type AudioTrack,
AudioWaveAnimation,
} from "@/components/audio-player";
import { cn } from "@/lib/utils";
import { Play, Pause, Radio } from "lucide-react";
import { Play, Pause } from "lucide-react";
type PlayAudioButtonProps = {
audioUrl: string;
@@ -85,7 +89,11 @@ export function PlayAudioButton({
>
{isThisPlaying ? (
<>
<Radio className="size-4 animate-pulse" />
<AudioWaveAnimation
paused={false}
colorClassName="bg-primary-foreground"
size="sm"
/>
<span>Now Playing</span>
</>
) : (
+2 -7
View File
@@ -3,7 +3,7 @@ export const dynamic = "force-dynamic";
import type { Metadata } from "next";
import Link from "next/link";
import { PageHeader } from "@/components/page-header";
import { buildOgMeta } from "@/lib/og";
import { ogForTranscriptions } from "@/lib/og";
import {
getTranscriptionYears,
getTranscriptionPlaces,
@@ -14,12 +14,7 @@ import { TranscriptionsNav } from "./transcriptions-nav";
import { TranscriptionsBrowser } from "./transcriptions-browser";
export function generateMetadata(): Metadata {
return buildOgMeta({
title: "Transcriptions",
detail: "3,700+ lectures & conversations (1966–1977)",
quote:
"Transcriptions of Śrīla Prabhupāda's lectures, morning walks, room conversations, and dialogues — the living voice of the Founder-Ācārya preserved in text.",
});
return ogForTranscriptions();
}
export default async function TranscriptionsPage({
+2 -2
View File
@@ -17,8 +17,8 @@ export async function generateMetadata({
const transcriptions = await getTranscriptionsByYear(year);
return buildOgMeta({
title: "Transcriptions",
detail: `${transcriptions.length} transcriptions from ${year}`,
quote: `Lectures and conversations of Śrīla Prabhupāda from ${year}.`,
detail: `${transcriptions.length} lectures & conversations from ${year}`,
quote: `Lectures and conversations of Śrīla Prabhupāda from ${year} — the living voice of the Founder-Ācārya preserved in text.`,
});
}