Skip to the content

Capsid menu

app/components/home-podcast.tsx

112 lines and 2 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.

Functions

The functions of home-podcast.tsx
FunctionLinesComplexityCoveredCRAPMutation
HomePodcast9 to 1138No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:36>36 to 442No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code

Imports

It imports app/components/enhance.tsx, app/lib/long-date.mjs, app/lib/podcast/clock.mjs, app/lib/podcast/feed.mjs, app/lib/seo.ts. Imported by app/routes/home.tsx.

Source

import { Enhance } from "~/components/enhance";
import { longDateUTC } from "~/lib/long-date.mjs";
import { clockTime } from "~/lib/podcast/clock.mjs";
import { PODCAST_SITE_URL, type PodcastEpisode } from "~/lib/podcast/feed.mjs";
import { GERMOMICS_X_URL } from "~/lib/seo";

// The hand-drawn controls are server markup marked `hidden` that the bundle swaps in, so a
// reader without script gets the native audio controls and never a button that does nothing.
export function HomePodcast({ episode }: { episode: PodcastEpisode | null }) {
  return (
    <section className="home-section home-scicomm" aria-labelledby="germomics-heading">
      <h2 id="germomics-heading" className="home-section-heading">
        Germomics
      </h2>
      {episode ? (
        <article className="podcast" data-podcast>
          <h3 className="podcast-title">
            <a href={episode.link}>{episode.title}</a>
          </h3>
          {/* Real separators, not a CSS gap, so reader mode and agents do not get one run-on word. */}
          <p className="podcast-meta">
            {[
              episode.season && episode.episode ? (
                <span key="number">
                  Season {episode.season}, episode {episode.episode}
                </span>
              ) : null,
              <time key="date" dateTime={episode.publishedAt}>
                {longDateUTC(new Date(episode.publishedAt))}
              </time>,
              episode.durationSeconds ? (
                <span key="length">{clockTime(episode.durationSeconds)}</span>
              ) : null,
            ]
              .filter(Boolean)
              .flatMap((item, i) =>
                i === 0
                  ? [item]
                  : [
                      <span key={`sep-${i}`} className="podcast-sep" aria-hidden="true">
                        {" ยท "}
                      </span>,
                      item,
                    ],
              )}
          </p>
          {episode.description ? <p className="podcast-description">{episode.description}</p> : null}
          <div className="podcast-player">
            <audio
              className="podcast-audio"
              controls
              preload="none"
              src={episode.audioUrl}
              aria-label={`Play ${episode.title}`}
            >
              <a href={episode.audioUrl}>Download the episode</a>
            </audio>
            {/* A named group, so Play and Seek carry the episode they act on. */}
            <div
              className="podcast-controls"
              data-podcast-controls
              role="group"
              aria-label={`Player for ${episode.title}`}
              hidden
            >
              <div className="podcast-scrub">
                <span className="podcast-time" data-podcast-elapsed>
                  0:00
                </span>
                <input
                  className="podcast-range"
                  type="range"
                  min={0}
                  max={episode.durationSeconds ?? 0}
                  step={1}
                  defaultValue={0}
                  aria-label="Seek"
                  data-podcast-seek
                />
                <span className="podcast-time" data-podcast-total>
                  {episode.durationSeconds ? clockTime(episode.durationSeconds) : "--:--"}
                </span>
              </div>
              <div className="podcast-buttons">
                <button type="button" className="podcast-btn" data-podcast-play>
                  Play
                </button>
                <button type="button" className="podcast-btn" data-podcast-skip="-15">
                  Back 15 s
                </button>
                <button type="button" className="podcast-btn" data-podcast-skip="30">
                  Forward 30 s
                </button>
              </div>
            </div>
          </div>
          <p className="home-more podcast-links">
            <a href={episode.link}>Episode page</a>
            <a href={PODCAST_SITE_URL}>germomics.com</a>
          </p>
          <Enhance module="podcast" />
        </article>
      ) : (
        <p className="home-more">
          The Germomics podcast is at <a href={PODCAST_SITE_URL}>germomics.com</a>.
        </p>
      )}
      <p className="home-more podcast-x">
        <a href={GERMOMICS_X_URL}>Germomics is also on X</a>
      </p>
    </section>
  );
}