fix(front): consistent widget display without duplicate results

This commit is contained in:
ArneBo 2025-02-19 14:10:27 +01:00
parent 2e63cad388
commit d74a8f637c
4 changed files with 23 additions and 26 deletions

View File

@ -3,8 +3,6 @@ import type { Album } from '~/types'
import { reactive, ref, watch } from 'vue' import { reactive, ref, watch } from 'vue'
import { useStore } from '~/store' import { useStore } from '~/store'
import { useI18n } from 'vue-i18n'
import axios from 'axios' import axios from 'axios'
@ -17,8 +15,6 @@ import Loader from '~/components/ui/Loader.vue'
import Pagination from '~/components/ui/Pagination.vue' import Pagination from '~/components/ui/Pagination.vue'
const { t } = useI18n()
interface Props { interface Props {
filters: Record<string, string | boolean> filters: Record<string, string | boolean>
showCount?: boolean showCount?: boolean
@ -56,7 +52,7 @@ const fetchData = async (url = 'albums/') => {
const response = await axios.get(url, { params }) const response = await axios.get(url, { params })
nextPage.value = response.data.next nextPage.value = response.data.next
count.value = response.data.count count.value = response.data.count
albums.push(...response.data.results) albums.splice(0, albums.length, ...response.data.results)
} catch (error) { } catch (error) {
useErrorHandler(error as Error) useErrorHandler(error as Error)
} }

View File

@ -59,7 +59,7 @@ const fetchData = async (url = 'channels/') => {
} }
onMounted(() => { onMounted(() => {
setTimeout(fetchData, 1000) fetchData()
}) })
watch([() => props.filters, page], watch([() => props.filters, page],
@ -71,16 +71,17 @@ watch([() => props.filters, page],
<template> <template>
<Section <Section
align-left align-left
small-items
:h2="title" :h2="title"
> >
<Loader v-if="isLoading" style="grid-column: 1 / -1;" /> <Loader v-if="isLoading" style="grid-column: 1 / -1;" />
<template <template
v-if="!isLoading && channels.length === 0" v-if="!isLoading && channels.length === 0"
style="grid-column: 1 / -1;"
> >
<empty-state <empty-state
:refresh="true" :refresh="true"
@refresh="fetchData('channels/')" @refresh="fetchData('channels/')"
style="grid-column: 1 / -1;"
/> />
</template> </template>
<channel-card <channel-card
@ -92,6 +93,7 @@ watch([() => props.filters, page],
v-if="channels && count > limit" v-if="channels && count > limit"
v-model:page="page" v-model:page="page"
:pages="Math.ceil((count || 0) / limit)" :pages="Math.ceil((count || 0) / limit)"
style="grid-column: 1 / -1;"
/> />
</Section> </Section>
</template> </template>

View File

@ -70,12 +70,10 @@ fetchData()
<playlist-widget <playlist-widget
:url="'playlists/'" :url="'playlists/'"
:filters="{scope: scope, playable: true, ordering: '-modification_date'}" :filters="{scope: scope, playable: true, ordering: '-modification_date'}"
> :title="t('components.library.Home.header.playlists')"
<template #title> :limit="12"
{{ t('components.library.Home.header.playlists') }} />
</template> <Spacer />
</playlist-widget>
<channels-widget <channels-widget
v-if="scope === 'all'" v-if="scope === 'all'"
:show-modification-date="true" :show-modification-date="true"
@ -83,24 +81,24 @@ fetchData()
:limit="8" :limit="8"
:title="t('components.library.Home.header.newChannels')" :title="t('components.library.Home.header.newChannels')"
/> />
<Spacer />
<track-widget <track-widget
:title="t('components.library.Home.header.recentlyListened')" :title="t('components.library.Home.header.recentlyListened')"
:url="'history/listenings/'" :url="'history/listenings/'"
:filters="{ scope, ordering: '-creation_date', ...qualityFilters }" :filters="{ scope, ordering: '-creation_date', ...qualityFilters }"
:websocket-handlers="['Listen']" :websocket-handlers="['Listen']"
/> />
<Spacer />
<track-widget <track-widget
:title="t('components.library.Home.header.recentlyFavorited')" :title="t('components.library.Home.header.recentlyFavorited')"
:url="'favorites/tracks/'" :url="'favorites/tracks/'"
:filters="{scope: scope, ordering: '-creation_date'}" :filters="{scope: scope, ordering: '-creation_date'}"
/> />
<Spacer />
<album-widget :filters="{scope: scope, playable: true, ordering: '-creation_date', ...qualityFilters}"> <album-widget
<template #title> :filters="{scope: scope, playable: true, ordering: '-creation_date', ...qualityFilters}"
{{ t('components.library.Home.header.recentlyAdded') }} :limit="12"
</template> :title="t('components.library.Home.header.recentlyAdded')"
</album-widget> />
</Layout> </Layout>
</template> </template>

View File

@ -51,7 +51,7 @@ const fetchData = async (url = props.url) => {
const response = await axios.get(url, { params }) const response = await axios.get(url, { params })
nextPage.value = response.data.next nextPage.value = response.data.next
count.value = response.data.count count.value = response.data.count
objects.push(...response.data.results) objects.splice(0, objects.length, ...response.data.results)
} catch (error) { } catch (error) {
useErrorHandler(error as Error) useErrorHandler(error as Error)
} }
@ -59,7 +59,7 @@ const fetchData = async (url = props.url) => {
isLoading.value = false isLoading.value = false
} }
setTimeout(fetchData, 1000) fetchData()
watch( watch(
[() => store.state.moderation.lastUpdate, page], [() => store.state.moderation.lastUpdate, page],
@ -71,9 +71,10 @@ watch(
<template> <template>
<Section <Section
align-left align-left
small-items
:h2="title" :h2="title"
> >
<Loader v-if="isLoading"/> <Loader v-if="isLoading" style="grid-column: 1 / -1;" />
<Alert <Alert
v-if="!isLoading && objects.length === 0" v-if="!isLoading && objects.length === 0"
style="grid-column: 1 / -1;" style="grid-column: 1 / -1;"
@ -102,8 +103,8 @@ watch(
/> />
</Section> </Section>
<Pagination <Pagination
v-if="objects && count > props.filters.limit" v-if="objects && count > (props.filters.limit as number)"
v-model:page="page" v-model:page="page"
:pages="Math.ceil((count || 0) / props.filters.limit)" :pages="Math.ceil((count || 0) / (props.filters.limit as number))"
/> />
</template> </template>