Skip to content
Snippets Groups Projects
Episode.vue 5.14 KiB
Newer Older
<!--
  - @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>
onny's avatar
onny committed
		<EpisodeEmpty v-show="loading" />
onny's avatar
onny committed
			<div v-show="!loading">
				<MediaHeader
					:imgurl="episode.imgURL"
					:title="episode.title"
onny's avatar
onny committed
					:author="podcastName"
					:htmlurl="`#/browse/show/${podcastId}`"
onny's avatar
onny committed
					:isshow="false">
					<button class="icon-play-white podcastButton button primary new-button">
						{{ t('podcast', 'Play episode') }}
					</button>
onny's avatar
onny committed
					<div class="episodeDetails">
						<span>
							<b>Duration:</b>
							{{ episode.duration_string }}
						</span>
						<span>
							<b>Publication date:</b>
							<span class="inline" :title="readableDate(episode.pubdate)">
onny's avatar
onny committed
								{{ readableTimeAgo(episode.pubdate) }}
							</span>
onny's avatar
onny committed
						</span>
					</div>
				</MediaHeader>
				<ContentCollapsable
					title="Episode notes">
			    <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">
onny's avatar
onny committed
									{{ readableDuration(chapter.start) }}
								</td>
								<td class="titleColumn">
									{{ chapter.title }}
				</ContentCollapsable>
import EpisodeEmpty from './placeholder/Episode'
import ContentCollapsable from '../components/ContentCollapsable'
import MediaHeader from '../components/MediaHeader'

import TimeAgo from 'javascript-time-ago'
onny's avatar
onny committed
import { FyydApi } from './../services/FyydApi'
const fyydClient = new FyydApi()

const timeAgo = new TimeAgo('en-US')

export default {
	name: 'Episode',
	components: {
		ContentCollapsable,
		MediaHeader,
onny's avatar
onny committed
		loading: true,
		episodeId: null,
		podcastId: null,
		podcastName: null,
onny's avatar
onny committed
		this.episodeId = this.$route.params.episodeId
		this.podcastId = this.$route.params.id
		this.queryEpisode(this.episodeId)
		this.queryPodcastName(this.podcastId)
onny's avatar
onny committed
		readableDuration(timestamp) {
			return timestamp.split('.')[0]
		},
onny's avatar
onny committed
			const date = new Date(datetime)
			return date.toDateString()
		},
		readableTimeAgo(datetime) {
			return timeAgo.format(Date.parse(datetime), 'twitter-minute-now')
		async queryEpisode(episodeId) {
onny's avatar
onny committed
			const queryURI = this.$apiUrl + '/episode'
			try {
				delete axios.defaults.headers.requesttoken
				await axios.get(queryURI, {
					params: {
						episode_id: episodeId,
					},
				})
					.then(function(response) {
onny's avatar
onny committed
						vm.processEpisode(response.data)
					})
			} catch (error) {
				showError(t('podcast', 'Could not fetch episode from remote API'))
onny's avatar
onny committed
		processEpisode(episode) {
onny's avatar
onny committed
			document.title = episode.data.title + ' - Podcast - Nextcloud'
onny's avatar
onny committed
			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'))
			}
onny's avatar
onny committed
.episodeDetails {
	display: block;
	margin-top: 10px;
	span {
		display: block;
	}
onny's avatar
onny committed
	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;
			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;
		}
onny's avatar
onny committed
		tr:hover, tr:focus, tr.mouseOver td {
			background-color: var(--color-background-hover);
		}