Skip to content

Commit 41738d2

Browse files
authored
Embed podcast on homepage (#219)
Embeds latest podcast on homepage Just above db-story-i on desktop, and just below the classifieds on tablet. Currently no display on mobile.
1 parent b672102 commit 41738d2

4 files changed

Lines changed: 87 additions & 4 deletions

File tree

components/LatestPodcast/index.jsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* LatestPodcast: renders the latest podcast episode's embedded player
3+
* on the home page. The WordPress post content typically contains an
4+
* iframe embed (Spotify, Apple Podcasts, etc.) which is rendered directly.
5+
*/
6+
import * as React from "react";
7+
/** @jsxImportSource @emotion/react */
8+
import { css } from "@emotion/core";
9+
10+
export default function LatestPodcast({ podcast }) {
11+
if (!podcast) return null;
12+
13+
return (
14+
<div
15+
css={css`
16+
/* Embedded player from WordPress content */
17+
iframe {
18+
max-width: 100%;
19+
border-radius: 8px;
20+
}
21+
22+
/* Hide non-embed content (text paragraphs, images, etc.)
23+
so only the player iframe shows */
24+
& > p,
25+
& > div:not(:has(iframe)),
26+
& > figure,
27+
& > img {
28+
display: none;
29+
}
30+
31+
/* Keep containers that hold iframes visible */
32+
& > div:has(iframe),
33+
& > p:has(iframe),
34+
& > figure:has(iframe) {
35+
display: block;
36+
}
37+
`}
38+
dangerouslySetInnerHTML={{ __html: podcast.content }}
39+
/>
40+
);
41+
}

layouts/Home/index.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Media from "react-media";
77

88
import ClassifiedsCard from "../../components/ClassifiedsCard";
99
import GamesCard from "components/GamesCard/GamesCard";
10+
import LatestPodcast from "../../components/LatestPodcast";
1011

1112
// Helper component for article cards with display type
1213
const ArticleCardWrapper = ({ id, card, displayType, priority }) => {
@@ -67,10 +68,21 @@ const GamesCardWrapper = () => (
6768
</div>
6869
);
6970

71+
// Helper component for latest podcast
72+
const LatestPodcastWrapper = ({ podcast }) => {
73+
if (!podcast) return null;
74+
return (
75+
<div className={css.card}>
76+
<LatestPodcast podcast={podcast} />
77+
</div>
78+
);
79+
};
80+
7081
export default function HomeLayout({
7182
posts,
7283
media,
7384
classifieds,
85+
latestPodcast = null,
7486
mappedBreaking = null
7587
}) {
7688
const cards = useMemo(() => {
@@ -202,6 +214,7 @@ export default function HomeLayout({
202214
classifieds={classifieds}
203215
/>
204216
</div>
217+
<LatestPodcastWrapper podcast={latestPodcast} />
205218
<ArticleCardWrapper
206219
id="f1"
207220
card={cards.f1ArticleCard}
@@ -305,6 +318,7 @@ export default function HomeLayout({
305318
<div style={{ textAlign: "center" }} className={css.card}>
306319
<broadstreet-zone zone-id="69405"></broadstreet-zone>
307320
</div>
321+
<LatestPodcastWrapper podcast={latestPodcast} />
308322
<StoryListWrapper id="i" card={cards.iArticleCard} />
309323
<StoryListWrapper id="j" card={cards.jArticleCard} />
310324
{/* Put twitter feed here */}

lib/fetchHomepageContent.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,16 @@ export async function fetchHomePageContent() {
131131
fetchWithTimeout(`${Config.apiUrl}/wp-json/wp/v2/posts?_embed&per_page=3&tags=${TAG_IDS.kTAGID}&${Config.articleCardFields}`),
132132
fetchWithTimeout(`${Config.apiUrl}/wp-json/wp/v2/posts?_embed&per_page=3&tags=${TAG_IDS.lTAGID}&${Config.articleCardFields}`),
133133
fetchWithTimeout(`${Config.apiUrl}/wp-json/wp/v2/posts?_embed&per_page=3&tags=${TAG_IDS.hTAGID}&${Config.articleCardFields}`),
134-
fetchWithTimeout(`${Config.apiUrl}/wp-json/wp/v2/classifieds?_embed&Featured=3`)
134+
fetchWithTimeout(`${Config.apiUrl}/wp-json/wp/v2/classifieds?_embed&Featured=3`),
135+
fetchWithTimeout(`${Config.apiUrl}/wp-json/wp/v2/categories?slug=podcasts`)
135136
];
136137

137138
const results = await Promise.allSettled(fetchPromises);
138139

139140
const [
140141
aStoryRes, bStoryRes, c1StoryRes, c2StoryRes, d1StoryRes, d2StoryRes, gStoryRes, mmStoryRes,
141142
f1StoryRes, f2StoryRes, iStoryRes, jStoryRes, kStoryRes, lStoryRes, hStoryRes,
142-
classifiedsRes
143+
classifiedsRes, podcastCatRes
143144
] = results.map((res, i) => {
144145
if (res.status === "fulfilled" && res.value.ok) return res.value;
145146

@@ -190,7 +191,33 @@ export async function fetchHomePageContent() {
190191

191192
const classifieds = await safeJsonArray(classifiedsRes);
192193

194+
// Fetch latest podcast post (two-step: category slug → latest post)
195+
let latestPodcast = null;
196+
try {
197+
const podcastCats = await safeJsonArray(podcastCatRes);
198+
if (podcastCats.length > 0) {
199+
const podcastCatId = podcastCats[0].id;
200+
const podcastPostRes = await fetchWithTimeout(
201+
`${Config.apiUrl}/wp-json/wp/v2/posts?_embed&per_page=1&categories=${podcastCatId}`
202+
);
203+
const podcastPosts = await safeJsonArray(podcastPostRes);
204+
if (podcastPosts.length > 0) {
205+
const post = podcastPosts[0];
206+
latestPodcast = {
207+
id: post.id ?? null,
208+
title: post.title?.rendered ?? "",
209+
content: post.content?.rendered ?? "",
210+
link: post.link ?? "",
211+
date: post.date ?? null,
212+
_embedded: filterEmbeddedData(post)
213+
};
214+
}
215+
}
216+
} catch (err) {
217+
console.error("Non-critical: failed to fetch latest podcast:", err.message);
218+
}
219+
193220
const filteredPosts = filterPostsData(posts);
194221

195-
return { posts: filteredPosts, multimediaPosts, classifieds };
222+
return { posts: filteredPosts, multimediaPosts, classifieds, latestPodcast };
196223
}

pages/index.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import EmailPopUp from "../components/EmailSignUp";
99
import { createStaticProps } from "lib/createStaticProps";
1010
import { fetchHomePageContent } from "lib/fetchHomepageContent";
1111

12-
function Index({ posts, multimediaPosts, classifieds }) {
12+
function Index({ posts, multimediaPosts, classifieds, latestPodcast }) {
1313
const [showNewsletterPopUp, setShowNewsletterPopUp] = useState(false);
1414

1515
/* Handle newsletter popping-up logic */
@@ -89,6 +89,7 @@ function Index({ posts, multimediaPosts, classifieds }) {
8989
<HomeLayout
9090
posts={posts}
9191
media={multimediaPosts}
92+
latestPodcast={latestPodcast}
9293
classifieds={(classifieds || [])
9394
.map(c => {
9495
try {

0 commit comments

Comments
 (0)