enhancement(front):use paginated page for playlist
fix(front):desable slow rendering component
This commit is contained in:
parent
6eddef1e1b
commit
2f79acdae0
|
@ -20,6 +20,7 @@ from funkwhale_api.music import utils as music_utils
|
||||||
from funkwhale_api.users.oauth import permissions as oauth_permissions
|
from funkwhale_api.users.oauth import permissions as oauth_permissions
|
||||||
|
|
||||||
from . import filters, models, parsers, renderers, serializers
|
from . import filters, models, parsers, renderers, serializers
|
||||||
|
from rest_framework.pagination import PageNumberPagination
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -138,9 +139,15 @@ class PlaylistViewSet(
|
||||||
plugins.TRIGGER_THIRD_PARTY_UPLOAD,
|
plugins.TRIGGER_THIRD_PARTY_UPLOAD,
|
||||||
track=plt.track,
|
track=plt.track,
|
||||||
)
|
)
|
||||||
serializer = serializers.PlaylistTrackSerializer(plts, many=True)
|
|
||||||
data = {"count": len(plts), "results": serializer.data}
|
# Apply pagination
|
||||||
return Response(data, status=200)
|
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(
|
@extend_schema(
|
||||||
operation_id="add_to_playlist", request=serializers.PlaylistAddManySerializer
|
operation_id="add_to_playlist", request=serializers.PlaylistAddManySerializer
|
||||||
|
|
|
@ -25,7 +25,6 @@ interface Props extends PlayOptionsProps {
|
||||||
|
|
||||||
// TODO(wvffle): Remove after https://github.com/vuejs/core/pull/4512 is merged
|
// TODO(wvffle): Remove after https://github.com/vuejs/core/pull/4512 is merged
|
||||||
isPlayable?: boolean
|
isPlayable?: boolean
|
||||||
tracks?: Track[]
|
|
||||||
artist?: Artist | null
|
artist?: Artist | null
|
||||||
album?: Album | null
|
album?: Album | null
|
||||||
playlist?: Playlist | null
|
playlist?: Playlist | null
|
||||||
|
@ -39,7 +38,6 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
isArtist: false,
|
isArtist: false,
|
||||||
isAlbum: false,
|
isAlbum: false,
|
||||||
|
|
||||||
tracks: () => [],
|
|
||||||
artist: null,
|
artist: null,
|
||||||
album: null,
|
album: null,
|
||||||
playlist: null,
|
playlist: null,
|
||||||
|
|
|
@ -245,7 +245,7 @@ const updatePage = (page: number) => {
|
||||||
<Loader v-if="isLoading" />
|
<Loader v-if="isLoading" />
|
||||||
|
|
||||||
<!-- For each item, build a row -->
|
<!-- For each item, build a row -->
|
||||||
|
<!--
|
||||||
<track-mobile-row
|
<track-mobile-row
|
||||||
v-for="(track, index) in allTracks"
|
v-for="(track, index) in allTracks"
|
||||||
:key="track.id"
|
:key="track.id"
|
||||||
|
@ -258,7 +258,7 @@ const updatePage = (page: number) => {
|
||||||
:is-artist="isArtist"
|
:is-artist="isArtist"
|
||||||
:is-album="isAlbum"
|
:is-album="isAlbum"
|
||||||
:is-podcast="isPodcast"
|
:is-podcast="isPodcast"
|
||||||
/>
|
/> -->
|
||||||
<Pagination
|
<Pagination
|
||||||
v-if="paginateResults"
|
v-if="paginateResults"
|
||||||
:pages="paginateBy"
|
:pages="paginateBy"
|
||||||
|
|
|
@ -4597,7 +4597,8 @@
|
||||||
"edit": "Edit",
|
"edit": "Edit",
|
||||||
"embed": "Embed",
|
"embed": "Embed",
|
||||||
"playAll": "Play all",
|
"playAll": "Play all",
|
||||||
"stopEdit": "Stop Editing"
|
"stopEdit": "Stop Editing",
|
||||||
|
"loadMoreTracks": "Load more tracks"
|
||||||
},
|
},
|
||||||
"empty": {
|
"empty": {
|
||||||
"noTracks": "There are no tracks in this playlist yet"
|
"noTracks": "There are no tracks in this playlist yet"
|
||||||
|
@ -4800,4 +4801,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -31,7 +31,7 @@ import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
// }
|
// }
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id: number
|
id: string
|
||||||
defaultEdit?: boolean
|
defaultEdit?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
})
|
})
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
const isLoadingMoreTracks = ref(false)
|
||||||
const edit = ref(props.defaultEdit)
|
const edit = ref(props.defaultEdit)
|
||||||
const playlist = ref<Playlist | null>(null)
|
const playlist = ref<Playlist | null>(null)
|
||||||
const playlistTracks = ref<PlaylistTrack[]>([])
|
const playlistTracks = ref<PlaylistTrack[]>([])
|
||||||
|
@ -57,17 +57,24 @@ const labels = computed(() => ({
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
|
const nextPage = ref<string | null>(null) // Tracks the next page URL
|
||||||
|
const previousPage = ref<string | null>(null) // Tracks the previous page URL
|
||||||
|
const totalTracks = ref<number>(0) // Total number of tracks
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [playlistResponse, tracksResponse] = await Promise.all([
|
const [playlistResponse, tracksResponse] = await Promise.all([
|
||||||
axios.get(`playlists/${props.id}/`),
|
axios.get(`playlists/${props.id}/`),
|
||||||
axios.get(`playlists/${props.id}/tracks/`)
|
axios.get(`playlists/${props.id}/tracks?page=1`)
|
||||||
])
|
])
|
||||||
|
|
||||||
playlist.value = playlistResponse.data
|
playlist.value = playlistResponse.data
|
||||||
fullPlaylistTracks.value = tracksResponse.data.results
|
fullPlaylistTracks.value = tracksResponse.data.results
|
||||||
|
nextPage.value = tracksResponse.data.next
|
||||||
|
previousPage.value = tracksResponse.data.previous
|
||||||
|
totalTracks.value = tracksResponse.data.count
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
useErrorHandler(error as Error)
|
useErrorHandler(error as Error)
|
||||||
}
|
}
|
||||||
|
@ -75,6 +82,25 @@ const fetchData = async () => {
|
||||||
isLoading.value = false
|
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()
|
fetchData()
|
||||||
|
|
||||||
const images = computed(() => {
|
const images = computed(() => {
|
||||||
|
@ -178,7 +204,6 @@ const shuffle = () => {}
|
||||||
<RenderedDescription
|
<RenderedDescription
|
||||||
:content="{ html: playlist.description }"
|
:content="{ html: playlist.description }"
|
||||||
:truncate-length="100"
|
:truncate-length="100"
|
||||||
:show-more="true"
|
|
||||||
/>
|
/>
|
||||||
<Layout
|
<Layout
|
||||||
flex
|
flex
|
||||||
|
@ -240,6 +265,9 @@ const shuffle = () => {}
|
||||||
:tracks="tracks"
|
:tracks="tracks"
|
||||||
:unique="false"
|
:unique="false"
|
||||||
/>
|
/>
|
||||||
|
<Button v-if="nextPage" @click="loadMoreTracks" primary :is-loading="isLoadingMoreTracks">
|
||||||
|
{{ t('views.playlists.Detail.button.loadMoreTracks') }}
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
<Alert
|
<Alert
|
||||||
v-else-if="!isLoading"
|
v-else-if="!isLoading"
|
||||||
|
|
Loading…
Reference in New Issue