From 2f79acdae0884e479b890bc5630812eb9c983ebd Mon Sep 17 00:00:00 2001 From: Petitminion Date: Fri, 30 May 2025 17:51:40 +0200 Subject: [PATCH] enhancement(front):use paginated page for playlist fix(front):desable slow rendering component --- api/funkwhale_api/playlists/views.py | 13 +++++-- .../src/components/audio/track/MobileRow.vue | 2 -- front/src/components/audio/track/Table.vue | 4 +-- front/src/locales/en_US.json | 5 +-- front/src/views/playlists/Detail.vue | 36 ++++++++++++++++--- 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/api/funkwhale_api/playlists/views.py b/api/funkwhale_api/playlists/views.py index 03e5e378d..5e04c237e 100644 --- a/api/funkwhale_api/playlists/views.py +++ b/api/funkwhale_api/playlists/views.py @@ -20,6 +20,7 @@ from funkwhale_api.music import utils as music_utils from funkwhale_api.users.oauth import permissions as oauth_permissions from . import filters, models, parsers, renderers, serializers +from rest_framework.pagination import PageNumberPagination logger = logging.getLogger(__name__) @@ -138,9 +139,15 @@ class PlaylistViewSet( plugins.TRIGGER_THIRD_PARTY_UPLOAD, track=plt.track, ) - serializer = serializers.PlaylistTrackSerializer(plts, many=True) - data = {"count": len(plts), "results": serializer.data} - return Response(data, status=200) + + # Apply pagination + paginator = PageNumberPagination() + paginator.page_size = 100 # Set the page size (number of items per page) + paginated_plts = paginator.paginate_queryset(plts, request) + + # Serialize the paginated data + serializer = serializers.PlaylistTrackSerializer(paginated_plts, many=True) + return paginator.get_paginated_response(serializer.data) @extend_schema( operation_id="add_to_playlist", request=serializers.PlaylistAddManySerializer diff --git a/front/src/components/audio/track/MobileRow.vue b/front/src/components/audio/track/MobileRow.vue index 39494a996..879338758 100644 --- a/front/src/components/audio/track/MobileRow.vue +++ b/front/src/components/audio/track/MobileRow.vue @@ -25,7 +25,6 @@ interface Props extends PlayOptionsProps { // TODO(wvffle): Remove after https://github.com/vuejs/core/pull/4512 is merged isPlayable?: boolean - tracks?: Track[] artist?: Artist | null album?: Album | null playlist?: Playlist | null @@ -39,7 +38,6 @@ const props = withDefaults(defineProps(), { isArtist: false, isAlbum: false, - tracks: () => [], artist: null, album: null, playlist: null, diff --git a/front/src/components/audio/track/Table.vue b/front/src/components/audio/track/Table.vue index 1e32ea901..2d4ed7a60 100644 --- a/front/src/components/audio/track/Table.vue +++ b/front/src/components/audio/track/Table.vue @@ -245,7 +245,7 @@ const updatePage = (page: number) => { - + (), { }) const store = useStore() - +const isLoadingMoreTracks = ref(false) const edit = ref(props.defaultEdit) const playlist = ref(null) const playlistTracks = ref([]) @@ -57,17 +57,24 @@ const labels = computed(() => ({ })) const isLoading = ref(false) +const nextPage = ref(null) // Tracks the next page URL +const previousPage = ref(null) // Tracks the previous page URL +const totalTracks = ref(0) // Total number of tracks + const fetchData = async () => { isLoading.value = true try { const [playlistResponse, tracksResponse] = await Promise.all([ axios.get(`playlists/${props.id}/`), - axios.get(`playlists/${props.id}/tracks/`) + axios.get(`playlists/${props.id}/tracks?page=1`) ]) playlist.value = playlistResponse.data fullPlaylistTracks.value = tracksResponse.data.results + nextPage.value = tracksResponse.data.next + previousPage.value = tracksResponse.data.previous + totalTracks.value = tracksResponse.data.count } catch (error) { useErrorHandler(error as Error) } @@ -75,6 +82,25 @@ const fetchData = async () => { isLoading.value = false } +const loadMoreTracks = async () => { + if (nextPage.value) { + isLoadingMoreTracks.value = true; // Set loading state for the button + try { + const response = await axios.get(nextPage.value); + + // Append new tracks to the existing list + fullPlaylistTracks.value = [...fullPlaylistTracks.value, ...response.data.results]; + + // Update pagination metadata + nextPage.value = response.data.next; + } catch (error) { + console.error("Error loading more tracks:", error); + } finally { + isLoadingMoreTracks.value = false; // Reset loading state + } + } +}; + fetchData() const images = computed(() => { @@ -178,7 +204,6 @@ const shuffle = () => {} {} :tracks="tracks" :unique="false" /> +