fix: Fixed playlist performance (#215)

This commit is contained in:
Mani
2024-05-19 01:29:51 +02:00
committed by GitHub
parent 4b7840ba1b
commit 2f63982ed6
4 changed files with 56 additions and 10 deletions
+5 -3
View File
@@ -194,7 +194,9 @@ export type PlaylistSearchResult = EntitySearchResult & {
export type PlaylistTrack = {
id: Scalars['String'];
next: Maybe<PlaylistTrack>;
playlist: Playlist;
previous: Maybe<PlaylistTrack>;
video: Video;
};
@@ -868,14 +870,14 @@ export type PlaylistDetailPagePlaylistQueryVariables = Exact<{
}>;
export type PlaylistDetailPagePlaylistQuery = { playlist: { id: string, name: string, visibility: PlaylistVisibility, tracks_count: number, forward: Array<{ id: string, video: { id: number, basename: string, tags: string, entries: Array<{ id: number, version: number | null, theme: { id: number, type: string, sequence: number | null, anime: { year: number | null, season: string | null, slug: string, name: string, images: Array<{ link: string, facet: string | null }> }, group: { name: string, slug: string } | null, song: { title: string | null, performances: Array<{ as: string | null, artist: { slug: string, name: string } }> } | null } }>, audio: { basename: string } } }>, user: { name: string } } | null };
export type PlaylistDetailPagePlaylistQuery = { playlist: { id: string, name: string, visibility: PlaylistVisibility, tracks_count: number, tracks: Array<{ id: string, video: { id: number, basename: string, tags: string, entries: Array<{ id: number, version: number | null, theme: { id: number, type: string, sequence: number | null, anime: { year: number | null, season: string | null, slug: string, name: string, images: Array<{ link: string, facet: string | null }> }, group: { name: string, slug: string } | null, song: { title: string | null, performances: Array<{ as: string | null, artist: { slug: string, name: string } }> } | null } }>, audio: { basename: string } }, previous: { id: string } | null, next: { id: string } | null }>, user: { name: string } } | null };
export type PlaylistDetailPageMeQueryVariables = Exact<{ [key: string]: never; }>;
export type PlaylistDetailPageMeQuery = { me: { user: { name: string } | null } };
export type PlaylistDetailPagePlaylistFragment = { id: string, name: string, visibility: PlaylistVisibility, tracks_count: number, forward: Array<{ id: string, video: { id: number, basename: string, tags: string, entries: Array<{ id: number, version: number | null, theme: { id: number, type: string, sequence: number | null, anime: { year: number | null, season: string | null, slug: string, name: string, images: Array<{ link: string, facet: string | null }> }, group: { name: string, slug: string } | null, song: { title: string | null, performances: Array<{ as: string | null, artist: { slug: string, name: string } }> } | null } }>, audio: { basename: string } } }>, user: { name: string } };
export type PlaylistDetailPagePlaylistFragment = { id: string, name: string, visibility: PlaylistVisibility, tracks_count: number, tracks: Array<{ id: string, video: { id: number, basename: string, tags: string, entries: Array<{ id: number, version: number | null, theme: { id: number, type: string, sequence: number | null, anime: { year: number | null, season: string | null, slug: string, name: string, images: Array<{ link: string, facet: string | null }> }, group: { name: string, slug: string } | null, song: { title: string | null, performances: Array<{ as: string | null, artist: { slug: string, name: string } }> } | null } }>, audio: { basename: string } }, previous: { id: string } | null, next: { id: string } | null }>, user: { name: string } };
type PlaylistDetailPageUser_UserAuth_Fragment = { name: string };
@@ -888,7 +890,7 @@ export type PlaylistDetailPageQueryVariables = Exact<{
}>;
export type PlaylistDetailPageQuery = { playlist: { id: string, name: string, visibility: PlaylistVisibility, tracks_count: number, forward: Array<{ id: string, video: { id: number, basename: string, tags: string, entries: Array<{ id: number, version: number | null, theme: { id: number, type: string, sequence: number | null, anime: { year: number | null, season: string | null, slug: string, name: string, images: Array<{ link: string, facet: string | null }> }, group: { name: string, slug: string } | null, song: { title: string | null, performances: Array<{ as: string | null, artist: { slug: string, name: string } }> } | null } }>, audio: { basename: string } } }>, user: { name: string } } | null, me: { user: { name: string } | null } };
export type PlaylistDetailPageQuery = { playlist: { id: string, name: string, visibility: PlaylistVisibility, tracks_count: number, tracks: Array<{ id: string, video: { id: number, basename: string, tags: string, entries: Array<{ id: number, version: number | null, theme: { id: number, type: string, sequence: number | null, anime: { year: number | null, season: string | null, slug: string, name: string, images: Array<{ link: string, facet: string | null }> }, group: { name: string, slug: string } | null, song: { title: string | null, performances: Array<{ as: string | null, artist: { slug: string, name: string } }> } | null } }>, audio: { basename: string } }, previous: { id: string } | null, next: { id: string } | null }>, user: { name: string } } | null, me: { user: { name: string } | null } };
export type GalleryPageQueryVariables = Exact<{ [key: string]: never; }>;
+10 -1
View File
@@ -76,6 +76,8 @@ export const INCLUDES = {
PlaylistTrack: {
video: "video",
playlist: "playlist",
previous: "previous",
next: "next",
},
UserAuth: {
permissions: "permissions",
@@ -113,7 +115,7 @@ const ALLOWED_INCLUDES: Record<string, Array<string>> = {
"animethemes.group",
"images",
"resources",
"studios",
"studios.images",
"animethemes.animethemeentries.videos.audio",
"animethemes.animethemeentries.videos.videoscript",
"animethemes.animethemeentries.videos.tracks.playlist",
@@ -179,6 +181,13 @@ const ALLOWED_INCLUDES: Record<string, Array<string>> = {
Playlist: [
"user",
"tracks",
"tracks.video.animethemeentries.animetheme.song.artists",
"tracks.video.audio",
"tracks.video.animethemeentries.animetheme.anime.images",
"tracks.video",
"tracks.video.animethemeentries.animetheme.group",
"tracks.previous",
"tracks.next",
],
PlaylistTrack: [
"video.animethemeentries.animetheme.anime.images",
+2
View File
@@ -261,6 +261,8 @@ const typeDefs = `
id: String!
video: Video!
playlist: Playlist!
previous: PlaylistTrack
next: PlaylistTrack
}
interface User {
+39 -6
View File
@@ -50,7 +50,7 @@ import { Reorder } from "framer-motion";
import axios from "lib/client/axios";
import { FeaturedTheme } from "components/featured-theme";
import { shuffle } from "lodash-es";
import createVideoSlug from "../../../utils/createVideoSlug";
import createVideoSlug from "utils/createVideoSlug";
import { useRouter } from "next/router";
const StyledDesktopOnly = styled.div`
@@ -112,6 +112,29 @@ function getRankComparator(name: string): Comparator<number> {
}
}
type LinkedList<T> = Array<{
id: string;
previous?: { id: string } | null;
next?: { id: string } | null;
} & T>;
function sortLinkedList<T>(list: LinkedList<T>) {
const lookUp = list.reduce((prev, curr) => {
prev[curr.id] = curr;
return prev;
}, {} as Record<string, typeof list[number]>);
let next = list.find((item) => !item.previous);
const sortedList = [];
while (next) {
sortedList.push(next);
next = next.next ? lookUp[next.next.id] : undefined;
}
return sortedList;
}
interface PlaylistDetailPageProps extends SharedPageProps, RequiredNonNullable<PlaylistDetailPageQuery> {}
interface PlaylistDetailPageParams extends ParsedUrlQuery {
@@ -140,6 +163,8 @@ export default function PlaylistDetailPage({ playlist: initialPlaylist, me: init
throw new Error("Playlist was removed or user lost auth.");
}
data.playlist.tracks = sortLinkedList(data.playlist.tracks);
return data.playlist;
},
{ fallbackData: initialPlaylist }
@@ -170,7 +195,7 @@ export default function PlaylistDetailPage({ playlist: initialPlaylist, me: init
const isOwner = me.user?.name === playlist.user.name;
const isRanking = playlist.name.startsWith("[#] ");
const tracks = [...playlist.forward].map((track, index) => ({ ...track, rank: index + 1 }));
const tracks = [...playlist.tracks].map((track, index) => ({ ...track, rank: index + 1 }));
const tracksSorted = [...tracks].sort(
sortTransformed(
getComparator(sortBy) ?? getRankComparator(sortBy),
@@ -224,7 +249,7 @@ export default function PlaylistDetailPage({ playlist: initialPlaylist, me: init
async function updateTrackOrder(newTracks: typeof tracks) {
await mutate({
...playlist,
forward: newTracks,
tracks: newTracks,
}, { revalidate: false });
}
@@ -307,8 +332,8 @@ export default function PlaylistDetailPage({ playlist: initialPlaylist, me: init
<Column style={{ "--gap": "24px" }}>
<StyledDesktopOnly>
<MultiCoverImage
key={JSON.stringify(playlist.forward)}
resourcesWithImages={playlist.forward.flatMap((track) => {
key={JSON.stringify(playlist.tracks.slice(0, 4))}
resourcesWithImages={playlist.tracks.slice(0, 4).flatMap((track) => {
const anime = track.video.entries[0].theme?.anime;
return anime ? [anime] : [];
@@ -399,7 +424,7 @@ PlaylistDetailPage.fragments = {
name
visibility
tracks_count
forward {
tracks {
id
video {
...VideoSummaryCardVideo
@@ -413,6 +438,12 @@ PlaylistDetailPage.fragments = {
}
}
}
previous {
id
}
next {
id
}
}
user {
name
@@ -453,6 +484,8 @@ export const getServerSideProps: GetServerSideProps<PlaylistDetailPageProps, Pla
};
}
data.playlist.tracks = sortLinkedList(data.playlist.tracks);
return {
props: {
...getSharedPageProps(apiRequests),