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>
<ShowEmpty v-show="pageLoading" />
<transition name="fade">
<div v-show="!pageLoading">
class="podcastHeaderBg"
:style="{ backgroundImage: `url(${podcast.smallImageURL})` }">
<div class="podcastHeader">
<div
class="podcastImage"
:style="{ backgroundImage: `url(${podcast.smallImageURL})` }" />
<div class="podcastDescription">
<h1>{{ podcast.title }}</h1>
<div class="podcastAuthor">
by <a :href="podcast.htmlURL" target="_blank">{{ podcast.author }}</a>
</div>
<div class="podcastControls">
<a href="#" class="button">Subscribe</a>
<ul class="podcastCategory">
<a v-for="(category, idx) in podcast.categories"
:key="idx"
:href="`#/browse/category/${podcast.categories[idx]}`">
<li>
{{ getCategoryName(podcast.categories[idx]) }}
</li>
</a>
</ul>
</div>
<vue-show-more-text
:text="podcast.description"
additional-container-css="padding: 0px;" />
</div>
<Table
v-resize="onResize"
:episodes="podcast.episodes"
@doPlay="doPlay" />
</template>
<script>
import Table from '../components/Table'
import { showError } from '@nextcloud/dialogs'
import axios from '@nextcloud/axios'
import vueShowMoreText from 'vue-show-more-text'
import { audioPlayer, doPlay } from '../services/player'
import { getCategoryName } from '../services/podcastApi'
export default {
name: 'Show',
components: {
Table,
}),
computed: {
player() {
return this.$store.state.player
},
},
watch: {
$route: 'onRoute',
'player.volume'(newVolume, oldVolume) {
if (audioPlayer !== null) {
audioPlayer.volume(newVolume)
}
},
'player.isPaused'(newState, oldState) {
if (newState === true && audioPlayer !== null) {
audioPlayer.pause()
} else if (newState === false && audioPlayer !== null) {
audioPlayer.play()
}
},
},
mounted() {
this.pageLoading = true
const podcastId = this.$route.params.id
this.queryPodcast(podcastId)
this.scroll()
},
methods: {
getCategoryName(categoryid) {
return getCategoryName(categoryid)
},
onResize({ width, height }) {
const contentHeight = document.getElementById('app-content-vue').scrollHeight
const tableHeight = height
if (tableHeight < contentHeight) {
this.preFill()
}
},
doPlay(episode) {
doPlay(episode)
},
preFill() {
const route = this.$route
console.log(route)
// this.queryPodcast(route.name)
},
/**
* Start playing a podcast episode
* @param {Object} episode Episode object
*/
async queryPodcast(podcastId) {
const vm = this
const queryURI = 'https://api.fyyd.de/0.2/podcast/episodes'
try {
delete axios.defaults.headers.requesttoken
await axios.get(queryURI, {
params: {
podcast_id: podcastId,
count: 20,
page: vm.nextPage,
},
})
.then(function(response) {
vm.nextPage = response.data.meta.paging.next_page
vm.processPodcast(response.data)
})
} catch (error) {
showError(t('podcast', 'Could not fetch stations from remote API'))
}
},
processPodcast(podcast) {
if (this.nextPage > 1) {
this.podcast.episodes = this.podcast.episodes.concat(podcast.data.episodes)
} else {
this.podcast = podcast.data
}
this.pageLoading = false
},
/**
* On scroll event, load more stations if bottom reached
*/
scroll() {
window.onscroll = () => {
if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
const podcastId = this.$route.params.id
this.queryPodcast(podcastId)
}
}
},
},
}
</script>
<style lang="scss">
.podcastHeaderBg {
background-size: cover;
background-position: center center;
background-attachment: fixed;
}
.podcastHeader {
width: 100%;
min-height: 300px;
display: flex;
color: white;
justify-content: center;
padding: 40px 20px;
/* gap: 30px; */
background-color: rgba(0, 0, 0, .7);
backdrop-filter: blur(8px);
text-shadow: 1px 1px 2px rgba(0,0,0,.5);
.button {
text-shadow: 0px 0px 0px;
}
width: 200px;
height: 200px;
background-position: center;
box-shadow: 0 4px 60px rgba(0,0,0,.5);
margin-right: 25px;
border-radius: 5px;
}
.podcastDescription {
max-width: 500px;
color: #ddd;
h1 {
font-size: 30px;
font-weight: bold;
line-height: 1.2em;
color: white;
}
.podcastAuthor {
padding-bottom: 5px;
a {
color: white;
}
}
.podcastControls {
display: flex;
align-items: center;
margin-bottom: 5px;
.button {
margin-right: 10px;
}
}
display: inline;
border: 1px solid var(--color-text-maxcontrast);
border-radius: var(--border-radius);
margin-right: 5px;
cursor: pointer;
color: var(--color-text-maxcontrast);
padding: 3px 6px;
ul.podcastCategory li:hover {
border: 1px solid white;
color: white;
}
@media only screen and (max-width: 500px) {
.podcastHeader {
flex-direction: column;
align-items: center;
.podcastImage {
margin-right: 0px;
margin-bottom: 25px;
}
.podcastDescription {
text-align: center;
.podcastControls {
justify-content: center;
}
}
}
}