fix: decode HTML entities in podroll episode and podcast titles
RSS feeds encode special characters as HTML entities; the backend serves them raw, causing " etc. to appear literally in the UI. Decode titles client-side using the browser's HTML parser. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+19
-4
@@ -286,10 +286,10 @@ function podrollApp() {
|
|||||||
fetch('/podrollapi/api/status').then(r => r.json())
|
fetch('/podrollapi/api/status').then(r => r.json())
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.episodes = episodesRes.items || [];
|
this.episodes = (episodesRes.items || []).map(ep => this.decodeEpisode(ep));
|
||||||
this.hasMore = episodesRes.hasMore || false;
|
this.hasMore = episodesRes.hasMore || false;
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
this.sources = sourcesRes.items || [];
|
this.sources = (sourcesRes.items || []).map(s => ({ ...s, title: this.decodeHtml(s.title) }));
|
||||||
this.status = statusRes;
|
this.status = statusRes;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.error = 'Failed to load podcasts: ' + err.message;
|
this.error = 'Failed to load podcasts: ' + err.message;
|
||||||
@@ -310,7 +310,7 @@ function podrollApp() {
|
|||||||
url += `&source=${encodeURIComponent(this.filterPodcast)}`;
|
url += `&source=${encodeURIComponent(this.filterPodcast)}`;
|
||||||
}
|
}
|
||||||
const res = await fetch(url).then(r => r.json());
|
const res = await fetch(url).then(r => r.json());
|
||||||
this.episodes = res.items || [];
|
this.episodes = (res.items || []).map(ep => this.decodeEpisode(ep));
|
||||||
this.hasMore = res.hasMore || false;
|
this.hasMore = res.hasMore || false;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.error = 'Failed to load episodes: ' + err.message;
|
this.error = 'Failed to load episodes: ' + err.message;
|
||||||
@@ -329,7 +329,7 @@ function podrollApp() {
|
|||||||
url += `&source=${encodeURIComponent(this.filterPodcast)}`;
|
url += `&source=${encodeURIComponent(this.filterPodcast)}`;
|
||||||
}
|
}
|
||||||
const res = await fetch(url).then(r => r.json());
|
const res = await fetch(url).then(r => r.json());
|
||||||
this.episodes = [...this.episodes, ...(res.items || [])];
|
this.episodes = [...this.episodes, ...(res.items || []).map(ep => this.decodeEpisode(ep))];
|
||||||
this.hasMore = res.hasMore || false;
|
this.hasMore = res.hasMore || false;
|
||||||
this.offset = newOffset;
|
this.offset = newOffset;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -374,6 +374,21 @@ function podrollApp() {
|
|||||||
return mb.toFixed(1) + ' MB';
|
return mb.toFixed(1) + ' MB';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
decodeHtml(str) {
|
||||||
|
if (!str) return str;
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.innerHTML = str;
|
||||||
|
return div.textContent;
|
||||||
|
},
|
||||||
|
|
||||||
|
decodeEpisode(ep) {
|
||||||
|
return {
|
||||||
|
...ep,
|
||||||
|
title: this.decodeHtml(ep.title),
|
||||||
|
podcast: ep.podcast ? { ...ep.podcast, title: this.decodeHtml(ep.podcast.title) } : ep.podcast
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
stripHtml(html) {
|
stripHtml(html) {
|
||||||
if (!html) return '';
|
if (!html) return '';
|
||||||
// Use textContent to safely extract text without executing HTML
|
// Use textContent to safely extract text without executing HTML
|
||||||
|
|||||||
Reference in New Issue
Block a user