Skip to content

Commit

Permalink
Front: Update Models to support standalone tracks
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthi-chaud committed Dec 21, 2024
1 parent 73df171 commit 54ba3a0
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 53 deletions.
11 changes: 9 additions & 2 deletions front/src/components/actions/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from "../icons";
import { NextRouter } from "next/router";
import Action from "./action";
import toast from "react-hot-toast";

export const GoToSongLyricsAction = (
songIdentifier: string | number,
Expand Down Expand Up @@ -76,10 +77,16 @@ export const GoToReleaseAction = (

export const GoToReleaseAsyncAction = (
router: NextRouter,
albumIdentifier: () => PromiseLike<number | string>,
albumIdentifier: () => PromiseLike<number | string | null>,
): Action => ({
onClick: () =>
albumIdentifier().then((id) => router.push(`/releases/${id}`)),
albumIdentifier().then((id) => {
if (id === null) {
toast.error("This resource is not attached to any album.");
} else {
router.push(`/releases/${id}`);
}
}),
label: "goToAlbum",
icon: <AlbumIcon />,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ const SongContextualMenu = (props: SongContextualMenuProps) => {
GoToArtistAction(props.song.artist.slug),
GoToReleaseAsyncAction(
router,
async () => (await getMasterTrack()).release.slug,
async () =>
(await getMasterTrack()).release?.slug ?? null,
),
],
[GoToSongLyricsAction(songSlug)],
Expand Down
18 changes: 11 additions & 7 deletions front/src/components/contextual-menu/track-contextual-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { RefreshTrackMetadataAction } from "../actions/refresh-metadata";
import ChangeSongType from "../actions/song-type";
import { useTranslation } from "react-i18next";
import { usePlayerContext } from "../../contexts/player";
import Action from "../actions/action";

type TrackContextualMenuProps = {
track: TrackWithRelations<"song" | "illustration">;
Expand All @@ -60,7 +61,8 @@ const TrackContextualMenu = (props: TrackContextualMenuProps) => {
const getPlayNextProps = () =>
Promise.all([
queryClient.fetchQuery(API.getArtist(props.track.song.artistId)),
queryClient.fetchQuery(API.getRelease(props.track.releaseId)),
props.track.releaseId &&
queryClient.fetchQuery(API.getRelease(props.track.releaseId)),
]).then(([artist, release]) => ({
track: props.track,
artist,
Expand All @@ -81,12 +83,14 @@ const TrackContextualMenu = (props: TrackContextualMenuProps) => {
<ContextualMenu
onSelect={props.onSelect}
actions={[
props.isVideo
? [
GoToArtistAction(props.track.song.artistId),
GoToReleaseAction(props.track.releaseId),
]
: [GoToReleaseAction(props.track.releaseId)],
[
props.isVideo
? GoToArtistAction(props.track.song.artistId)
: undefined,
props.track.releaseId
? GoToReleaseAction(props.track.releaseId)
: undefined,
].filter((a): a is Action => a !== undefined),
[GoToSongLyricsAction(props.track.song.slug)],
[
PlayNextAction(getPlayNextProps, playNext),
Expand Down
13 changes: 9 additions & 4 deletions front/src/components/list-item/song-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type SongItemProps<
song: SongWithRelations<
"artist" | "featuring" | "master" | "illustration"
>,
) => Promise<string>)[];
) => Promise<string | null>)[];
};

export const SongGroupItem = <
Expand Down Expand Up @@ -92,7 +92,7 @@ const SongItem = <
const artist = song?.artist;
const { playTrack } = usePlayerContext();
const queryClient = useQueryClient();
const [subtitle, setSubtitle] = useState(
const [subtitle, setSubtitle] = useState<string | null | undefined>(
subtitles?.length
? ((<br />) as unknown as string)
: song
Expand All @@ -105,8 +105,13 @@ const SongItem = <
Promise.allSettled(subtitles.map((s) => s(song))).then((r) =>
setSubtitle(
r
.map((s) => (s as PromiseFulfilledResult<string>).value)
.join(" • "),
.map(
(s) =>
(s as PromiseFulfilledResult<string | null>)
.value,
)
.filter((s): s is string => s !== null)
.join(" • ") || null,
),
);
}
Expand Down
3 changes: 1 addition & 2 deletions front/src/components/list-item/track-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ const TrackItem = ({ track, onClick }: TrackItemProps) => {
}
onClick={
track &&
release &&
(() => {
onClick?.();
queryClient
Expand All @@ -67,7 +66,7 @@ const TrackItem = ({ track, onClick }: TrackItemProps) => {
})
}
title={track?.name}
secondTitle={release?.name}
secondTitle={release?.name ?? null}
trailing={
<Grid
container
Expand Down
58 changes: 37 additions & 21 deletions front/src/components/player/controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -413,33 +413,49 @@ const ExpandedPlayerControls = (
}}
>
{props.artist && props.track ? (
<Link
href={`/releases/${props.track.releaseId}`}
style={{
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
<Button
onClick={() =>
props.onExpand(false)
}
!props.track.releaseId ? (
<Typography
sx={{
textTransform: "none",
color: "inherit",
width: "100%",
fontWeight: "bold",
...playerTextStyle,
}}
>
<Typography
{props.track?.name}
</Typography>
) : (
<Link
href={
props.track.releaseId
? `/releases/${props.track.releaseId}`
: {}
}
style={{
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
<Button
onClick={() =>
props.track?.releaseId &&
props.onExpand(false)
}
sx={{
fontWeight: "bold",
...playerTextStyle,
textTransform: "none",
color: "inherit",
width: "100%",
}}
>
{props.track?.name}
</Typography>
</Button>
</Link>
<Typography
sx={{
fontWeight: "bold",
...playerTextStyle,
}}
>
{props.track?.name}
</Typography>
</Button>
</Link>
)
) : (
<Skeleton animation={false} width={"70%"} />
)}
Expand Down
4 changes: 2 additions & 2 deletions front/src/models/track.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const Track = Resource.concat(
/**
* Unique identifier of the parent release
*/
releaseId: yup.number().required(),
releaseId: yup.number().required().nullable(),
/**
* Title of the track
*/
Expand Down Expand Up @@ -86,7 +86,7 @@ export type TrackInclude = "song" | "release" | "illustration";

const TrackRelations = yup.object({
song: yup.lazy(() => Song.required()),
release: Release.required(),
release: Release.required().nullable(),
illustration: Illustration.required().nullable(),
});

Expand Down
13 changes: 8 additions & 5 deletions front/src/pages/artists/[slugOrId]/songs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ const prepareSSR = async (
artistQuery(artistIdentifier),
...songs.pages
.flatMap(({ items }) => items)
.filter(({ master }) => master.releaseId)
.map(({ master }) =>
API.getRelease(master.releaseId, ["album"]),
API.getRelease(master.releaseId!, ["album"]),
),
],
infiniteQueries: [],
Expand All @@ -83,10 +84,12 @@ const ArtistSongPage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({
const router = useRouter();
const isRareSongs = isRareSongsPage(router);
const queryClient = useQueryClient();
const getTrackReleaseName = (track: Track) =>
queryClient
.fetchQuery(API.getRelease(track.releaseId))
.then((release) => release.name);
const getTrackReleaseName = (track: Track): Promise<string | null> =>
track.releaseId
? queryClient
.fetchQuery(API.getRelease(track.releaseId))
.then((release) => release.name)
: Promise.resolve(null);
const artistIdentifier =
props?.artistIdentifier ?? getSlugOrId(router.query);
const artist = useQuery(artistQuery, artistIdentifier);
Expand Down
33 changes: 24 additions & 9 deletions front/src/pages/playlists/[slugOrId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import RelationPageHeader from "../../../components/relation-page-header/relatio
import { GetPropsTypesFrom, Page } from "../../../ssr";
import getSlugOrId from "../../../utils/getSlugOrId";
import {
Query,
prepareMeeloQuery,
useQueries,
useQuery,
Expand Down Expand Up @@ -89,7 +90,16 @@ const prepareSSR = async (
additionalProps: { playlistIdentifier },
queries: [
playlistQuery(playlistIdentifier),
...entries.map((entry) => API.getRelease(entry.master.releaseId)),
...entries
.map((entry) =>
entry.master.releaseId
? API.getRelease(entry.master.releaseId)
: undefined,
)
.filter(
(promise): promise is Query<Release> =>
promise !== undefined,
),
],
};
};
Expand Down Expand Up @@ -219,13 +229,15 @@ const PlaylistPage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({
const playlist = useQuery(playlistQuery, playlistIdentifier);
const entriesQuery = useQuery(playlistEntriesQuery, playlistIdentifier);
const masterTracksReleaseQueries = useQueries(
...(entriesQuery.data?.map(
({
master,
}): Parameters<
typeof useQuery<Release, Parameters<typeof API.getRelease>>
> => [API.getRelease, master.releaseId],
) ?? []),
...(entriesQuery.data
?.filter(({ master }) => master.releaseId)
.map(
({
master,
}): Parameters<
typeof useQuery<Release, Parameters<typeof API.getRelease>>
> => [API.getRelease, master.releaseId ?? undefined],
) ?? []),
);
const reorderMutation = useMutation((reorderedEntries: number[]) => {
return API.reorderPlaylist(playlistIdentifier, reorderedEntries)
Expand All @@ -240,7 +252,10 @@ const PlaylistPage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({
const releases = masterTracksReleaseQueries.map((query) => query.data);
const resolvedReleases = releases.filter((data) => data !== undefined);

if (resolvedReleases.length !== entriesQuery.data?.length) {
if (
resolvedReleases.length !==
entriesQuery.data?.filter((t) => t.master.releaseId != null).length
) {
return undefined;
}

Expand Down

0 comments on commit 54ba3a0

Please sign in to comment.