105 lines
2.5 KiB
Vue
105 lines
2.5 KiB
Vue
<template>
|
|
<div>
|
|
<Loading v-if="loading" />
|
|
<ul v-if="!loading">
|
|
<Episode
|
|
v-for="episode in filteredEpisodes"
|
|
:key="episode.guid"
|
|
:display-actions="!selected.length"
|
|
:episode="episode"
|
|
:selected="selected.includes(episode)"
|
|
:url="url"
|
|
@select="select" />
|
|
</ul>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { hasEnded, isListening } from '../../utils/status.ts'
|
|
import Episode from './Episode.vue'
|
|
import type { EpisodeInterface } from '../../utils/types.ts'
|
|
import Loading from '../Atoms/Loading.vue'
|
|
import axios from '@nextcloud/axios'
|
|
import { decodeUrl } from '../../utils/url.ts'
|
|
import { generateUrl } from '@nextcloud/router'
|
|
import { mapState } from 'pinia'
|
|
import { showError } from '../../utils/toast.ts'
|
|
import { t } from '@nextcloud/l10n'
|
|
import { usePlayer } from '../../store/player.ts'
|
|
import { useSettings } from '../../store/settings.ts'
|
|
|
|
export default {
|
|
name: 'Episodes',
|
|
components: {
|
|
Episode,
|
|
Loading,
|
|
},
|
|
data: () => ({
|
|
episodes: [] as EpisodeInterface[],
|
|
loading: true,
|
|
selected: [] as EpisodeInterface[],
|
|
}),
|
|
computed: {
|
|
...mapState(usePlayer, ['episode']),
|
|
...mapState(useSettings, ['filters']),
|
|
filteredEpisodes() {
|
|
return this.episodes.filter((episode) => {
|
|
if (!this.filters.listened && this.hasEnded(episode)) {
|
|
return false
|
|
}
|
|
if (!this.filters.listening && this.isListening(episode)) {
|
|
return false
|
|
}
|
|
if (!this.filters.unlistened && !this.isListening(episode)) {
|
|
return false
|
|
}
|
|
return true
|
|
})
|
|
},
|
|
url() {
|
|
return decodeUrl(this.$route.params.url as string)
|
|
},
|
|
},
|
|
watch: {
|
|
episode() {
|
|
if (this.episode) {
|
|
this.episodes = this.episodes.map((e) =>
|
|
e.url === this.episode?.url ? this.episode : e,
|
|
)
|
|
}
|
|
},
|
|
},
|
|
async mounted() {
|
|
try {
|
|
this.loading = true
|
|
const episodes = await axios.get<EpisodeInterface[]>(
|
|
generateUrl('/apps/repod/episodes/list?url={url}', {
|
|
url: this.url,
|
|
}),
|
|
)
|
|
this.episodes = [...episodes.data].sort(
|
|
(a, b) =>
|
|
new Date(b.pubDate?.date || '').getTime() -
|
|
new Date(a.pubDate?.date || '').getTime(),
|
|
)
|
|
} catch (e) {
|
|
console.error(e)
|
|
showError(t('repod', 'Could not fetch episodes'))
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
methods: {
|
|
hasEnded,
|
|
isListening,
|
|
select(episode: EpisodeInterface) {
|
|
if (this.selected.includes(episode)) {
|
|
this.selected = this.selected.filter((e) => e !== episode)
|
|
} else {
|
|
this.selected.push(episode)
|
|
}
|
|
},
|
|
},
|
|
}
|
|
</script>
|