Skip to content

Commit

Permalink
Front: Genre Page: Add Tab router
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthi-chaud committed Aug 10, 2024
1 parent a86f89e commit c950206
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 52 deletions.
21 changes: 18 additions & 3 deletions front/src/components/tab-router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
*/

import { NextRouter, useRouter } from "next/router";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";

/**
* Utilitary to update router when using tabs
Expand All @@ -29,11 +30,17 @@ export const useTabRouter = <TabValue extends string>(
getTabValueFromRouter: (
router: NextRouter,
) => string | string[] | undefined,
// This should persist the tab change in the router
onTabChange: (newTab: TabValue) => void,
defaultTab: TabValue,
...otherTabs: TabValue[]
) => {
const router = useRouter();
const tabs = [defaultTab, ...otherTabs];
const { t } = useTranslation();
const tabs = useMemo(
() => [defaultTab, ...otherTabs],
[defaultTab, otherTabs],
);
const getTabFromQuery = () =>
tabs.find(
(availableTab) =>
Expand All @@ -44,10 +51,18 @@ export const useTabRouter = <TabValue extends string>(
getTabFromQuery() ?? defaultTab,
);

//Handle going back in history
useEffect(() => {
const tabFromQuery = getTabFromQuery();
selectTab(tabFromQuery ?? defaultTab);
const newTab = tabFromQuery ?? defaultTab;
if (newTab !== selectedTab) {
selectTab(tabFromQuery ?? defaultTab);
}
}, [router.asPath]);
useEffect(() => {
onTabChange(selectedTab);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedTab]);

return { selectedTab, selectTab };
};
118 changes: 80 additions & 38 deletions front/src/pages/genres/[slugOrId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { Box, Skeleton, Typography } from "@mui/material";
import { Box, Skeleton, Tab, Tabs, Typography } from "@mui/material";
import { useRouter } from "next/router";
import SelectableInfiniteView from "../../components/infinite/selectable-infinite-view";
import { useQuery } from "../../api/use-query";
import getSlugOrId from "../../utils/getSlugOrId";
import { GetPropsTypesFrom, Page } from "../../ssr";
import API from "../../api/api";
import { NextPageContext } from "next";
import { Head } from "../../components/head";
import { useTabRouter } from "../../components/tab-router";
import InfiniteArtistView from "../../components/infinite/infinite-resource-view/infinite-artist-view";
import InfiniteAlbumView from "../../components/infinite/infinite-resource-view/infinite-album-view";
import InfiniteSongView from "../../components/infinite/infinite-resource-view/infinite-song-view";
import { useTranslation } from "react-i18next";

const prepareSSR = (context: NextPageContext) => {
const genreIdentifier = getSlugOrId(context.query);
Expand All @@ -51,10 +55,23 @@ const prepareSSR = (context: NextPageContext) => {
};
};

const tabs = ["artist", "album", "song"] as const;

const GenrePage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({ props }) => {
const router = useRouter();
const { t } = useTranslation();
const genreIdentifier = props?.genreIdentifier ?? getSlugOrId(router.query);
const genre = useQuery(API.getGenre, genreIdentifier);
const { selectedTab, selectTab } = useTabRouter(
(r) => r.query.t,
(newTab) =>
router.push(`/genres/${genreIdentifier}?t=${newTab}`, undefined, {
shallow: true,
}),
"album",
"artist",
"song",
);

return (
<Box sx={{ width: "100%" }}>
Expand All @@ -72,42 +89,67 @@ const GenrePage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({ props }) => {
{genre.data?.name ?? <Skeleton width={"100px"} />}
</Typography>
</Box>
<SelectableInfiniteView
enabled={true}
artistQuery={({ library }, { sortBy, order }) =>
API.getArtists(
{
genre: genreIdentifier,
library: library ?? undefined,
},
{ sortBy, order },
["illustration"],
)
}
albumQuery={({ library, type }, { sortBy, order }) =>
API.getAlbums(
{
genre: genreIdentifier,
type,
library: library ?? undefined,
},
{ sortBy, order },
["artist", "illustration"],
)
}
songQuery={({ library, type, random }, { sortBy, order }) =>
API.getSongs(
{
genre: genreIdentifier,
type,
random,
library: library ?? undefined,
},
{ sortBy, order },
["artist", "featuring", "master", "illustration"],
)
}
/>
<Tabs
value={selectedTab}
onChange={(__, tabName) => selectTab(tabName)}
variant="scrollable"
>
{tabs.map((value, index) => (
<Tab
key={index}
value={value}
sx={{ minWidth: "fit-content", flex: 1 }}
label={t(value)}
/>
))}
</Tabs>
<Box sx={{ paddingBottom: 2 }} />
{selectedTab == "artist" && (
<InfiniteArtistView
query={({ library, sortBy, order }) =>
API.getArtists(
{
genre: genreIdentifier,
library: library ?? undefined,
},
{ sortBy, order },
["illustration"],
)
}
/>
)}
{selectedTab == "album" && (
<InfiniteAlbumView
defaultAlbumType={null}
query={({ library, type, sortBy, order }) =>
API.getAlbums(
{
genre: genreIdentifier,
type,
library: library ?? undefined,
},
{ sortBy, order },
["artist", "illustration"],
)
}
/>
)}
{selectedTab == "song" && (
<InfiniteSongView
query={({ library, type, random, sortBy, order }) =>
API.getSongs(
{
genre: genreIdentifier,
type,
random,
library: library ?? undefined,
},
{ sortBy, order },
["artist", "featuring", "master", "illustration"],
)
}
/>
)}
</Box>
);
};
Expand Down
1 change: 1 addition & 0 deletions front/src/pages/search/[[...query]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const SearchPage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({ props }) => {
setDebounceId(undefined);
}, 500),
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [inputValue]);
useEffect(() => {
return () => {
Expand Down
17 changes: 6 additions & 11 deletions front/src/pages/songs/[slugOrId]/[...tab].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@ const prepareSSR = (context: NextPageContext) => {
const tabs = ["lyrics", "versions", "tracks", "more"] as const;

const SongPage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({ props }) => {
const { selectTab, selectedTab } = useTabRouter(
const { selectedTab, selectTab } = useTabRouter(
(router) => router.query.tab,
(newTab) =>
router.push(`/songs/${songIdentifier}/${newTab}`, undefined, {
shallow: true,
}),
...tabs,
);
const { t } = useTranslation();
Expand Down Expand Up @@ -141,16 +145,7 @@ const SongPage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({ props }) => {
<Divider sx={{ paddingY: 1 }} />
<Tabs
value={selectedTab}
onChange={(__, tabName) => {
selectTab(tabName);
router.push(
`/songs/${songIdentifier}/${tabName}`,
undefined,
{
shallow: true,
},
);
}}
onChange={(__, tabName) => selectTab(tabName)}
variant="scrollable"
>
{tabs.map((value, index) => (
Expand Down

0 comments on commit c950206

Please sign in to comment.