<!-- - @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> <div 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="`#/browse/author/${podcast.author}`">{{ 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> </div> </div> <Table v-show="!pageLoading && podcast.episodes.length > 0" v-resize="onResize" :episodes="podcast.episodes" @doPlay="doPlay" /> <EmptyContent v-if="pageLoading" icon="icon-loading" /> </div> </template> <script> import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent' 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, EmptyContent, vueShowMoreText, }, data: () => ({ podcast: { episodes: [], }, pageLoading: false, nextPage: 0, }), 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 console.log(tableHeight, contentHeight) if (tableHeight < contentHeight) { this.preFill() } }, doPlay(episode) { doPlay(episode) }, preFill() { const route = this.$route console.log('lol') 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; } .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; } .podcastImage { width: 200px; height: 200px; background-size: cover; 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; } } ul.podcastCategory li { 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; } } } } </style>