Adding podcast episodes (#27462)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
01985c11db
commit
f7eab14f6b
@ -0,0 +1,18 @@
|
||||
---
|
||||
title: 'Nx Enterprise Podcast Episode 1: Hicham El Hammouchi'
|
||||
slug: 'hicham-el-hammouchi-podcast-1'
|
||||
authors: ['Zack DeRose']
|
||||
tags: [podcast]
|
||||
cover_image: /blog/images/2024-06-18/ep-1-hicham.png
|
||||
podcastYoutubeId: 8iiLB_2djZ8
|
||||
podcastSpotifyId: 24yagCNpu9EGj0fCwSDQkj
|
||||
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/899a2e4c-2e56-4dfa-a3e3-e69eb216f2b0/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-1-hicham-el-hamouchi
|
||||
podcastAppleUrl: https://podcasters.spotify.com/pod/show/enterprise-software/episodes/The-Enterprise-Software-Podcast-By-Nx-1--Hicham-El-Hamouchi-e2l0302
|
||||
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-186891511/
|
||||
---
|
||||
|
||||
In this episode, Zack DeRose from Nx chats with Hicham El Hammouchi, a veteran in enterprise software. Hicham dives into his background, sharing his career journey and the wealth of experience he's gathered along the way.
|
||||
|
||||
They tackle the tough challenges that companies face in software development. Hicham offers practical insights and real-life examples from his own career, making complex issues easier to understand. He also shares some tried-and-true strategies for overcoming these hurdles, emphasizing the importance of teamwork and effective project management.
|
||||
|
||||
As the chat continues, Zack and Hicham explore the latest tech trends and innovations that are shaking up the industry. Hicham's forward-thinking views provide a sneak peek into the future of enterprise software. They also discuss detailed case studies of successful projects, highlighting the importance of staying focused on customer needs and feedback.
|
||||
18
docs/blog/2024-07-19-podcast-episode-2-tine-kondo.md
Normal file
18
docs/blog/2024-07-19-podcast-episode-2-tine-kondo.md
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
title: 'Nx Enterprise Podcast Episode 2: Tine Kondo'
|
||||
slug: 'tine-kondo-podcast-2'
|
||||
authors: ['Zack DeRose']
|
||||
tags: [podcast]
|
||||
cover_image: /blog/images/2024-07-19/ep-2-tine.png
|
||||
podcastYoutubeId: Nzf3BmymfEo
|
||||
podcastSpotifyId: 0CCQaWCln7rvwkkVvsyxsk
|
||||
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/53934cd9-c521-441e-8523-8b947ed207ca/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-2-tine-kondo
|
||||
podcastAppleUrl: https://podcasts.apple.com/us/podcast/the-enterprise-software-podcast-by-nx-2-tine-kondo/id1752704996?i=1000662764990
|
||||
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-197335640/
|
||||
---
|
||||
|
||||
In this episode, welcome Nx Champion and Nx Expert, Tine Kondo. Our discussion highlights how Nx is poised to make an impact in the Java space.
|
||||
|
||||
We touch on the difficulties larger organizations face when merging PRs in a timely manner, emphasizing how a monorepo alleviates the headache of coordinating multiple PRs across various repositories, and share firsthand experiences and frustrations with traditional multi-repo setups, underscoring the benefits of a unified approach.
|
||||
|
||||
In particular, Nx's new plugin: [@nx/gradle](/nx-api/gradle) is of interest, and Tine provides some valuable insight on the impact this plugin can make, as well as the importance for Maven support.
|
||||
16
docs/blog/2024-08-14-podcast-episode-3-ahmed-elsakaan.md
Normal file
16
docs/blog/2024-08-14-podcast-episode-3-ahmed-elsakaan.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
title: 'Nx Enterprise Podcast Episode 3: Ahmed Elsakaan'
|
||||
slug: 'ahmed-elsakaan-podcast-3'
|
||||
authors: ['Zack DeRose']
|
||||
tags: [podcast]
|
||||
cover_image: /blog/images/2024-08-14/ep-3-ahmed.png
|
||||
podcastYoutubeId: l_b6EOXqYRg
|
||||
podcastSpotifyId: 4d4oE8B3y9BmECZ3P4uvDP
|
||||
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/28209cf9-1b88-48b5-a798-7b24c843e9b1/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-3-ahmed-elsakaan
|
||||
podcastAppleUrl: https://podcasts.apple.com/us/podcast/the-enterprise-software-podcast-by-nx-3-ahmed-elsakaan/id1752704996?i=1000665363260
|
||||
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-205664230/
|
||||
---
|
||||
|
||||
In this episode we welcome Nx Champion and creator of [noodle](https://noodle.run) and [OrbitKit](https://orbitkit.dev/): Ahmed Elsakaan.
|
||||
|
||||
As a monorepo enthusiast, we explore Ahmed's thoughts on monorepos and how these tools can add value to developers - both in the space of setting up your monorepo (like Nx does) and in the space of creating reusable customizable modules (like OrbitKit is attempting).
|
||||
BIN
docs/blog/images/2024-06-18/ep-1-hicham.png
Normal file
BIN
docs/blog/images/2024-06-18/ep-1-hicham.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 159 KiB |
BIN
docs/blog/images/2024-07-19/ep-2-tine.png
Normal file
BIN
docs/blog/images/2024-07-19/ep-2-tine.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 180 KiB |
BIN
docs/blog/images/2024-08-14/ep-3-ahmed.png
Normal file
BIN
docs/blog/images/2024-08-14/ep-3-ahmed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 754 KiB |
@ -68,6 +68,11 @@ export class BlogApi {
|
||||
ogImageType: type,
|
||||
filePath,
|
||||
slug,
|
||||
podcastYoutubeId: frontmatter.podcastYoutubeId,
|
||||
podcastSpotifyId: frontmatter.podcastSpotifyId,
|
||||
podcastIHeartUrl: frontmatter.podcastIHeartUrl,
|
||||
podcastAppleUrl: frontmatter.podcastAppleUrl,
|
||||
podcastAmazonUrl: frontmatter.podcastAmazonUrl,
|
||||
};
|
||||
const isDevelopment = process.env.NODE_ENV === 'development';
|
||||
const shouldIncludePost = !frontmatter.draft || isDevelopment;
|
||||
|
||||
@ -11,8 +11,11 @@ export type BlogPostDataEntry = {
|
||||
pinned?: boolean;
|
||||
filePath: string;
|
||||
slug: string;
|
||||
ogImage: string;
|
||||
ogImageType: string;
|
||||
podcastYoutubeId?: string;
|
||||
podcastSpotifyId?: string;
|
||||
podcastAmazonUrl?: string;
|
||||
podcastAppleUrl?: string;
|
||||
podcastIHeartUrl?: string;
|
||||
};
|
||||
|
||||
export type BlogAuthor = {
|
||||
|
||||
@ -4,6 +4,7 @@ import Image from 'next/image';
|
||||
import { BlogAuthors } from './authors';
|
||||
import { ChevronLeftIcon } from '@heroicons/react/24/outline';
|
||||
import { renderMarkdown } from '@nx/nx-dev/ui-markdoc';
|
||||
import { EpisodePlayer } from './episode-player';
|
||||
|
||||
export interface BlogDetailsProps {
|
||||
post: BlogPostDataEntry;
|
||||
@ -65,7 +66,18 @@ export function BlogDetails({ post }: BlogDetailsProps) {
|
||||
{post.title}
|
||||
</h1>
|
||||
</header>
|
||||
{post.cover_image && (
|
||||
{post.podcastYoutubeId && post.podcastSpotifyId ? (
|
||||
<div className="mx-auto mb-16 w-full max-w-screen-md">
|
||||
<EpisodePlayer
|
||||
podcastYoutubeId={post.podcastYoutubeId}
|
||||
podcastSpotifyId={post.podcastSpotifyId}
|
||||
amazonUrl={post.podcastAmazonUrl}
|
||||
appleUrl={post.podcastAppleUrl}
|
||||
iHeartUrl={post.podcastIHeartUrl}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
post.cover_image && (
|
||||
<div className="mx-auto mb-16 aspect-[1.7] w-full max-w-screen-md">
|
||||
<Image
|
||||
className="h-full w-full object-cover md:rounded-md"
|
||||
@ -75,6 +87,7 @@ export function BlogDetails({ post }: BlogDetailsProps) {
|
||||
height={735}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
<div className="mx-auto min-w-0 max-w-3xl flex-auto px-4 pb-24 lg:px-0 lg:pb-16">
|
||||
<div className="relative">
|
||||
|
||||
149
nx-dev/ui-blog/src/lib/episode-player.tsx
Normal file
149
nx-dev/ui-blog/src/lib/episode-player.tsx
Normal file
@ -0,0 +1,149 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
AmazonMusicIcon,
|
||||
ApplePodcastsIcon,
|
||||
IHeartRadioIcon,
|
||||
SpotifyIcon,
|
||||
} from '@nx/nx-dev/ui-icons';
|
||||
import Link from 'next/link';
|
||||
|
||||
export function EpisodePlayer({
|
||||
podcastYoutubeId,
|
||||
podcastSpotifyId,
|
||||
amazonUrl,
|
||||
appleUrl,
|
||||
iHeartUrl,
|
||||
}: {
|
||||
podcastYoutubeId: string;
|
||||
podcastSpotifyId: string;
|
||||
amazonUrl?: string;
|
||||
appleUrl?: string;
|
||||
iHeartUrl?: string;
|
||||
}) {
|
||||
const [viewType, setViewType] = useState<ViewMode>('audio');
|
||||
return (
|
||||
<div className="flex basis-2/3 flex-col items-center justify-center gap-2">
|
||||
{viewType === 'audio' ? (
|
||||
<>
|
||||
<iframe
|
||||
style={{ borderRadius: '12px' }}
|
||||
src={`https://open.spotify.com/embed/episode/${podcastSpotifyId}?utm_source=generator&theme=0`}
|
||||
width="100%"
|
||||
height="152"
|
||||
frameBorder="0"
|
||||
allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
|
||||
loading="lazy"
|
||||
key="audio"
|
||||
></iframe>
|
||||
</>
|
||||
) : (
|
||||
<iframe
|
||||
style={{ borderRadius: '12px' }}
|
||||
width="100%"
|
||||
height="400"
|
||||
src={`https://www.youtube.com/embed/${podcastYoutubeId}?si=8rkgAzJfLfd-hxAA`}
|
||||
title="YouTube video player"
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerPolicy="strict-origin-when-cross-origin"
|
||||
allowFullScreen
|
||||
key="video"
|
||||
></iframe>
|
||||
)}
|
||||
<div className="container my-1 flex">
|
||||
<div className="basis-1/2">
|
||||
{viewType === 'audio' && (
|
||||
<PlatformLinks
|
||||
amazonUrl={amazonUrl}
|
||||
appleUrl={appleUrl}
|
||||
iHeartUrl={iHeartUrl}
|
||||
podcastSpotifyId={podcastSpotifyId}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex basis-1/2 flex-wrap justify-end gap-6 sm:gap-4">
|
||||
<button
|
||||
className="flex shrink-0 items-center gap-2 text-slate-400 hover:text-slate-800 dark:text-slate-600 dark:hover:text-slate-200"
|
||||
onClick={() => setViewType(getOpposite(viewType))}
|
||||
>
|
||||
Switch to {getOpposite(viewType) === 'audio' ? 'Audio' : 'Video'}
|
||||
</button>
|
||||
<Link
|
||||
className="flex shrink-0 items-center gap-2 text-slate-400 hover:text-slate-800 dark:text-slate-600 dark:hover:text-slate-200"
|
||||
href="/podcast"
|
||||
>
|
||||
More Podcasts
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function PlatformLinks({
|
||||
amazonUrl,
|
||||
appleUrl,
|
||||
iHeartUrl,
|
||||
podcastSpotifyId,
|
||||
}: {
|
||||
amazonUrl?: string;
|
||||
appleUrl?: string;
|
||||
iHeartUrl?: string;
|
||||
podcastSpotifyId: string;
|
||||
}): JSX.Element {
|
||||
const platforms = [
|
||||
{
|
||||
name: 'Amazon Music',
|
||||
url: amazonUrl,
|
||||
icon: AmazonMusicIcon,
|
||||
},
|
||||
{
|
||||
name: 'Apple Podcasts',
|
||||
url: appleUrl,
|
||||
icon: ApplePodcastsIcon,
|
||||
},
|
||||
{
|
||||
name: 'iHeartRadio',
|
||||
url: iHeartUrl,
|
||||
icon: IHeartRadioIcon,
|
||||
},
|
||||
{
|
||||
name: 'Spotify',
|
||||
url: `https://open.spotify.com/episode/${podcastSpotifyId}?si=Nqd7F40hQXugagH8oDxxpA`,
|
||||
icon: SpotifyIcon,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ul className="flex flex-wrap gap-6 sm:gap-4">
|
||||
{platforms
|
||||
.filter((platform) => !!platform.url)
|
||||
.map((platform) => {
|
||||
return (
|
||||
<li
|
||||
key={platform.name}
|
||||
className="inline-block cursor-pointer place-items-center rounded-2xl border border-slate-100 bg-white p-4 text-slate-600 transition-all hover:scale-[1.02] hover:text-slate-950 dark:border-slate-800/60 dark:bg-slate-950 dark:text-slate-400 dark:hover:text-white"
|
||||
>
|
||||
<a
|
||||
href={platform.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex h-full w-full items-center justify-center"
|
||||
>
|
||||
<platform.icon className="h-6 w-6 shrink-0" />
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
type ViewMode = 'audio' | 'video';
|
||||
|
||||
function getOpposite(viewMode: ViewMode): ViewMode {
|
||||
if (viewMode === 'audio') return 'video';
|
||||
return 'audio';
|
||||
}
|
||||
@ -20,7 +20,7 @@ export function PodcastListItem({ podcast, episode }: PodcastListItemProps) {
|
||||
prefetch={false}
|
||||
>
|
||||
<span className="w-1/2 flex-none text-balance text-slate-500 sm:w-8/12 dark:text-white">
|
||||
Episode {episode}: {podcast.title}
|
||||
{podcast.title}
|
||||
</span>
|
||||
<span className="hidden w-2/12 flex-none sm:inline-block">
|
||||
<time dateTime={podcast.date}>{formattedDate}</time>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user