mirror of
https://github.com/AnimeThemes/animethemes-web.git
synced 2026-07-11 01:24:31 +02:00
fix: Fixed playlist performance (#215)
This commit is contained in:
@@ -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; }>;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -261,6 +261,8 @@ const typeDefs = `
|
||||
id: String!
|
||||
video: Video!
|
||||
playlist: Playlist!
|
||||
previous: PlaylistTrack
|
||||
next: PlaylistTrack
|
||||
}
|
||||
|
||||
interface User {
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user