repod/src/components/Feed/Episodes.vue
Michel Roux 69d1ce44a4
All checks were successful
repod / xml (push) Successful in 25s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 1m17s
repod / release (push) Has been skipped
feat: add multiselect
2024-12-10 14:05:52 +01:00

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>