diff --git a/src/app/Nav.vue b/src/app/Nav.vue
index 4cd329c..013788e 100644
--- a/src/app/Nav.vue
+++ b/src/app/Nav.vue
@@ -38,6 +38,10 @@
Starred
+
+ Podcasts
+
+
Radio
diff --git a/src/library/TrackList.vue b/src/library/TrackList.vue
index 962085c..f295557 100644
--- a/src/library/TrackList.vue
+++ b/src/library/TrackList.vue
@@ -54,9 +54,14 @@
-
+
+
+ {{ item.album }}
+
+
+
{{ item.album }}
-
+
|
{{ $formatDuration(item.duration) }}
diff --git a/src/library/podcast/PodcastDetails.vue b/src/library/podcast/PodcastDetails.vue
new file mode 100644
index 0000000..0e10c28
--- /dev/null
+++ b/src/library/podcast/PodcastDetails.vue
@@ -0,0 +1,88 @@
+
+
+ {{ podcast.name }}
+ {{ podcast.description }}
+
+
+
+
+ #
+ |
+
+ Title
+ |
+
+ Duration
+ |
+
+ Actions
+ |
+
+
+
+
+
+
+ |
+
+ {{ item.title }}
+
+ {{ item.description }}
+
+ |
+
+
+ {{ $formatDuration(item.duration) }}
+
+ |
+
+
+ |
+
+
+
+
+
+
diff --git a/src/library/podcast/PodcastLibrary.vue b/src/library/podcast/PodcastLibrary.vue
new file mode 100644
index 0000000..da4f6af
--- /dev/null
+++ b/src/library/podcast/PodcastLibrary.vue
@@ -0,0 +1,42 @@
+
+
+
+ Podcasts
+
+
+ Refresh
+
+
+
+
+
+
+ {{ item.trackCount }} episodes
+
+
+
+
+
+
diff --git a/src/player/Player.vue b/src/player/Player.vue
index 0f77e2c..04d1634 100644
--- a/src/player/Player.vue
+++ b/src/player/Player.vue
@@ -25,7 +25,7 @@
{{ track.title }}
- {{ track.artist }}
+ {{ track.artist || track.album || track.description }}
diff --git a/src/shared/api.ts b/src/shared/api.ts
index 26c1737..7f24cc7 100644
--- a/src/shared/api.ts
+++ b/src/shared/api.ts
@@ -318,6 +318,20 @@ export class API {
return this.get('rest/deleteInternetRadioStation', { id })
}
+ async getPodcasts(): Promise {
+ const response = await this.get('rest/getPodcasts')
+ return (response?.podcasts?.channel || []).map(this.normalizePodcast, this)
+ }
+
+ async getPodcast(id: string): Promise {
+ const response = await this.get('rest/getPodcasts', { id })
+ return this.normalizePodcast(response?.podcasts?.channel[0])
+ }
+
+ async refreshPodcasts(): Promise {
+ return this.get('rest/refreshPodcasts')
+ }
+
async scan(): Promise {
return this.get('rest/startScan')
}
@@ -387,6 +401,33 @@ export class API {
}
}
+ private normalizePodcast(podcast: any): any {
+ const image = podcast.originalImageUrl
+ return {
+ id: podcast.id,
+ name: podcast.title,
+ description: podcast.description,
+ image: image,
+ url: podcast.url,
+ trackCount: podcast.episode.length,
+ tracks: podcast.episode.map((episode: any, index: number) => ({
+ id: episode.id,
+ title: episode.title,
+ duration: episode.duration,
+ starred: false,
+ track: podcast.episode.length - index,
+ album: podcast.title,
+ albumId: null,
+ artist: '',
+ artistId: null,
+ image,
+ url: episode.streamId ? this.getStreamUrl(episode.streamId) : null,
+ description: podcast.description,
+ playable: episode.status === 'completed',
+ })),
+ }
+ }
+
private getCoverArtUrl(item: any) {
if (!item.coverArt) {
return undefined
diff --git a/src/shared/components/Icon.vue b/src/shared/components/Icon.vue
index 67881f1..cd0277b 100644
--- a/src/shared/components/Icon.vue
+++ b/src/shared/components/Icon.vue
@@ -26,6 +26,7 @@
BIconBoxArrowRight,
BIconPersonFill,
BIconPersonCircle,
+ BIconRss,
BIconX,
} from 'bootstrap-vue'
@@ -53,6 +54,7 @@
BIconBoxArrowRight,
BIconPersonFill,
BIconPersonCircle,
+ BIconRss,
BIconX,
},
props: {
diff --git a/src/shared/router.ts b/src/shared/router.ts
index 97e6d21..203930c 100644
--- a/src/shared/router.ts
+++ b/src/shared/router.ts
@@ -10,6 +10,8 @@ import GenreDetails from '@/library/genre/GenreDetails.vue'
import GenreLibrary from '@/library/genre/GenreLibrary.vue'
import Starred from '@/library/starred/Starred.vue'
import RadioStations from '@/library/radio/RadioStations.vue'
+import PodcastDetails from '@/library/podcast/PodcastDetails.vue'
+import PodcastLibrary from '@/library/podcast/PodcastLibrary.vue'
import Playlist from '@/playlist/Playlist.vue'
import PlaylistList from '@/playlist/PlaylistList.vue'
import SearchResult from '@/search/SearchResult.vue'
@@ -86,6 +88,17 @@ export function setupRouter(auth: AuthService) {
path: '/radio',
component: RadioStations,
},
+ {
+ name: 'podcasts',
+ path: '/podcasts',
+ component: PodcastLibrary,
+ },
+ {
+ name: 'podcast',
+ path: '/podcast/:id',
+ component: PodcastDetails,
+ props: true,
+ },
{
name: 'playlists',
path: '/playlists',
|