⚡ Episodes (no paging)
This commit is contained in:
@@ -2,27 +2,30 @@ import { css } from "lit";
|
||||
|
||||
export const styles = css`
|
||||
:host {
|
||||
list-style: none;
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"title title"
|
||||
"date feed"
|
||||
"content content";
|
||||
grid-template-rows:
|
||||
fit-content
|
||||
fit-content
|
||||
1fr;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
h2 {
|
||||
grid-area: title;
|
||||
text-wrap: balance;
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: var(--primary-color, #007bff);
|
||||
}
|
||||
|
||||
time {
|
||||
font-size: 0.85rem;
|
||||
time, .feed {
|
||||
color: #666;
|
||||
}
|
||||
time { grid-area: date; }
|
||||
.feed { grid-area: feed; }
|
||||
.content {
|
||||
grid-area: content;
|
||||
max-height: 3.5lh;
|
||||
overflow: auto;
|
||||
font-size: .9em;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -7,20 +7,23 @@ describe("EpisodeListItem", () => {
|
||||
const mockEpisode: Episode = {
|
||||
id: "1",
|
||||
title: "Test Episode",
|
||||
published: "2023-01-01T00:00:00Z",
|
||||
audio_url: "http://example.com/audio.mp3",
|
||||
date: 1781258812000,
|
||||
content: "<b>Test content</b>",
|
||||
feedId: "2",
|
||||
feedName: "Test Feed",
|
||||
};
|
||||
|
||||
it("renders correctly with episode data", async () => {
|
||||
const el = await fixture(html`<episode-list-card .episode=${mockEpisode}></episode-list-card>`);
|
||||
const title = el.shadowRoot!.querySelector(".title");
|
||||
const time = el.shadowRoot!.querySelector("time");
|
||||
const audioLink = el.shadowRoot!.querySelector(".audio-link");
|
||||
|
||||
const title = el.shadowRoot!.querySelector("h2");
|
||||
expect(title?.textContent).to.equal("Test Episode");
|
||||
const time = el.shadowRoot!.querySelector("time");
|
||||
expect(time?.textContent).to.contain("2023");
|
||||
expect(audioLink).to.exist;
|
||||
expect(audioLink?.getAttribute("href")).to.equal("http://example.com/audio.mp3");
|
||||
const feed = el.shadowRoot!.querySelector(".feed");
|
||||
expect(feed?.textContent).to.equal("Test Feed");
|
||||
const content = el.shadowRoot!.querySelector(".content");
|
||||
expect(content?.innerHTML.trim()).to.equal("<b>Test content</b>");
|
||||
});
|
||||
|
||||
it("renders empty when no episode is provided", async () => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { LitElement, html } from "lit";
|
||||
import { property, customElement } from "lit/decorators.js";
|
||||
import { type Episode } from "@/api/episodes.js";
|
||||
import { styles } from "./index.css.js";
|
||||
import { templateContent } from "lit/directives/template-content.js";
|
||||
|
||||
@customElement("c-episode-list-card")
|
||||
export class EpisodeListCard extends LitElement {
|
||||
@@ -11,13 +12,24 @@ export class EpisodeListCard extends LitElement {
|
||||
|
||||
override render() {
|
||||
if (!this.episode) return html``;
|
||||
const { id, title, content, date, feedId, feedName }= this.episode;
|
||||
const dateString = new Date(date).toLocaleDateString();
|
||||
const template = document.createElement("template");
|
||||
try {
|
||||
// @ts-expect-error 2551
|
||||
template.setHTML(content);
|
||||
} catch (e) {
|
||||
template.innerText = content;
|
||||
}
|
||||
return html`
|
||||
<a href="/episodes/${this.episode.id}">
|
||||
<div class="info">
|
||||
${this.episode.title}
|
||||
<time datetime="${this.episode.published}">${new Date(this.episode.published).toLocaleDateString()}</time>
|
||||
</div>
|
||||
</a>
|
||||
<h2>
|
||||
<a href="/episodes/${id}">${title}</a>
|
||||
</h2>
|
||||
<time datetime="${date}">${dateString}</time>
|
||||
<a class="feed" href="/feeds/${feedId}">${feedName}</a>
|
||||
<div class="content">
|
||||
${templateContent(template)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user