<!-- - @copyright Copyright (c) 2020 Jonas Heinrich - - @author Jonas Heinrich <onny@project-insanity.org> - - @license GNU AGPL version 3 or any later version - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - --> <template> <div> <EpisodeEmpty v-show="loading" /> <transition name="fade"> <div v-show="!loading"> <MediaHeader :imgurl="episode.imgURL" :title="episode.title" :author="podcastName" :htmlurl="`#/browse/show/${podcastId}`" :isshow="false"> <button class="icon-play-white podcastButton button primary new-button"> {{ t('podcast', 'Play episode') }} </button> <div class="episodeDetails"> <span> <b>Duration:</b> {{ episode.duration_string }} </span> <span> <b>Publication date:</b> <span class="inline" :title="readableDate(episode.pubdate)"> {{ readableTimeAgo(episode.pubdate) }} </span> </span> </div> </MediaHeader> <ContentCollapsable title="Episode notes"> <!-- eslint-disable --> <p v-html="episode.description" /> <!-- eslint-enable --> </ContentCollapsable> <ContentCollapsable v-show="episode.chapters" title="Episode chapters"> <table class="chapterTable"> <tbody> <tr v-for="(chapter, idx) in episode.chapters" :key="idx"> <td class="timeColumn"> {{ readableDuration(chapter.start) }} </td> <td class="titleColumn"> {{ chapter.title }} </td> </tr> </tbody> </table> </ContentCollapsable> </div> </transition> </div> </template> <script> import EpisodeEmpty from './placeholder/Episode' import ContentCollapsable from '../components/ContentCollapsable' import MediaHeader from '../components/MediaHeader' import TimeAgo from 'javascript-time-ago' import { FyydApi } from './../services/FyydApi' const fyydClient = new FyydApi() const timeAgo = new TimeAgo('en-US') export default { name: 'Episode', components: { EpisodeEmpty, ContentCollapsable, MediaHeader, }, data: () => ({ episode: {}, loading: true, episodeId: null, podcastId: null, podcastName: null, }), mounted() { this.episodeId = this.$route.params.episodeId this.podcastId = this.$route.params.id this.queryEpisode(this.episodeId) this.queryPodcastName(this.podcastId) }, methods: { readableDuration(timestamp) { return timestamp.split('.')[0] }, readableDate(datetime) { const date = new Date(datetime) return date.toDateString() }, readableTimeAgo(datetime) { return timeAgo.format(Date.parse(datetime), 'twitter-minute-now') }, async queryEpisode(episodeId) { const vm = this const queryURI = this.$apiUrl + '/episode' try { delete axios.defaults.headers.requesttoken await axios.get(queryURI, { params: { episode_id: episodeId, }, }) .then(function(response) { vm.processEpisode(response.data) }) } catch (error) { showError(t('podcast', 'Could not fetch episode from remote API')) } }, processEpisode(episode) { this.episode = episode.data document.title = episode.data.title + ' - Podcast - Nextcloud' this.loading = false }, async queryPodcastName(podcastId) { const vm = this const queryURI = this.$apiUrl + '/podcast' try { delete axios.defaults.headers.requesttoken await axios.get(queryURI, { params: { podcast_id: podcastId, count: 0, }, }) .then(function(response) { vm.podcastName = response.data.data.title }) } catch (error) { showError(t('podcast', 'Could not fetch podcast from remote API')) } }, }, } </script> <style lang="scss"> .episodeDetails { display: block; margin-top: 10px; span { display: block; } span.inline { display: inline; } } .episodeContent { p { padding: 10px 30px; max-width: 550px; margin-top: 1px; } } table.chapterTable { width: 100%; min-width: 250px; table-layout:fixed; position: relative; margin-top: 1px; tbody { td { padding: 15px 0px; padding-left: 30px; font-style: normal; border-bottom: 1px solid var(--color-border); cursor: pointer; } tr { height: 30px; background-color: var(--color-background-light); transition: opacity 500ms ease 0s; } tr td * { cursor: pointer; } td.timeColumn { width: 120px; color: #1976d2; } td.titleColumn { padding-left: 0px; } tr:hover, tr:focus, tr.mouseOver td { background-color: var(--color-background-hover); } } } </style>