[FEAT] add album direct diaplay
This commit is contained in:
parent
30bc82edb3
commit
90fb1ed411
@ -35,11 +35,11 @@
|
|||||||
"@dnd-kit/modifiers": "7.0.0",
|
"@dnd-kit/modifiers": "7.0.0",
|
||||||
"@dnd-kit/sortable": "8.0.0",
|
"@dnd-kit/sortable": "8.0.0",
|
||||||
"@dnd-kit/utilities": "3.2.2",
|
"@dnd-kit/utilities": "3.2.2",
|
||||||
"@emotion/react": "11.13.0",
|
"@emotion/react": "11.13.3",
|
||||||
"@emotion/styled": "11.13.0",
|
"@emotion/styled": "11.13.0",
|
||||||
"allotment": "1.20.2",
|
"allotment": "1.20.2",
|
||||||
"css-mediaquery": "0.1.2",
|
"css-mediaquery": "0.1.2",
|
||||||
"dayjs": "1.11.12",
|
"dayjs": "1.11.13",
|
||||||
"history": "5.3.0",
|
"history": "5.3.0",
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-color-palette": "7.2.2",
|
"react-color-palette": "7.2.2",
|
||||||
@ -48,13 +48,13 @@
|
|||||||
"react-day-picker": "9.0.8",
|
"react-day-picker": "9.0.8",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
"react-error-boundary": "4.0.13",
|
"react-error-boundary": "4.0.13",
|
||||||
"react-focus-lock": "2.12.1",
|
"react-focus-lock": "2.13.2",
|
||||||
"react-icons": "5.3.0",
|
"react-icons": "5.3.0",
|
||||||
"react-popper": "2.3.0",
|
"react-popper": "2.3.0",
|
||||||
"react-router-dom": "6.26.1",
|
"react-router-dom": "6.26.1",
|
||||||
"react-select": "5.8.0",
|
"react-select": "5.8.0",
|
||||||
"react-simple-keyboard": "3.7.144",
|
"react-simple-keyboard": "3.7.147",
|
||||||
"react-sticky-el": "2.1.0",
|
"react-sticky-el": "2.1.1",
|
||||||
"react-use": "17.5.1",
|
"react-use": "17.5.1",
|
||||||
"react-use-draggable-scroll": "0.4.7",
|
"react-use-draggable-scroll": "0.4.7",
|
||||||
"react-virtuoso": "4.10.1",
|
"react-virtuoso": "4.10.1",
|
||||||
@ -65,7 +65,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@chakra-ui/styled-system": "2.9.2",
|
"@chakra-ui/styled-system": "2.9.2",
|
||||||
"@playwright/test": "1.46.0",
|
"@playwright/test": "1.46.1",
|
||||||
"@storybook/addon-actions": "8.2.9",
|
"@storybook/addon-actions": "8.2.9",
|
||||||
"@storybook/addon-essentials": "8.2.9",
|
"@storybook/addon-essentials": "8.2.9",
|
||||||
"@storybook/addon-links": "8.2.9",
|
"@storybook/addon-links": "8.2.9",
|
||||||
@ -73,19 +73,19 @@
|
|||||||
"@storybook/react": "8.2.9",
|
"@storybook/react": "8.2.9",
|
||||||
"@storybook/react-vite": "8.2.9",
|
"@storybook/react-vite": "8.2.9",
|
||||||
"@storybook/theming": "8.2.9",
|
"@storybook/theming": "8.2.9",
|
||||||
"@testing-library/jest-dom": "6.4.8",
|
"@testing-library/jest-dom": "6.5.0",
|
||||||
"@testing-library/react": "16.0.0",
|
"@testing-library/react": "16.0.0",
|
||||||
"@testing-library/user-event": "14.5.2",
|
"@testing-library/user-event": "14.5.2",
|
||||||
"@trivago/prettier-plugin-sort-imports": "4.3.0",
|
"@trivago/prettier-plugin-sort-imports": "4.3.0",
|
||||||
"@types/jest": "29.5.12",
|
"@types/jest": "29.5.12",
|
||||||
"@types/node": "22.3.0",
|
"@types/node": "22.5.0",
|
||||||
"@types/react": "18.3.3",
|
"@types/react": "18.3.4",
|
||||||
"@types/react-dom": "18.3.0",
|
"@types/react-dom": "18.3.0",
|
||||||
"@types/react-sticky-el": "1.0.7",
|
"@types/react-sticky-el": "1.0.7",
|
||||||
"@typescript-eslint/eslint-plugin": "8.1.0",
|
"@typescript-eslint/eslint-plugin": "8.2.0",
|
||||||
"@typescript-eslint/parser": "8.1.0",
|
"@typescript-eslint/parser": "8.2.0",
|
||||||
"@vitejs/plugin-react": "4.3.1",
|
"@vitejs/plugin-react": "4.3.1",
|
||||||
"eslint": "9.9.0",
|
"eslint": "9.9.1",
|
||||||
"eslint-plugin-codeceptjs": "1.3.0",
|
"eslint-plugin-codeceptjs": "1.3.0",
|
||||||
"eslint-plugin-import": "2.29.1",
|
"eslint-plugin-import": "2.29.1",
|
||||||
"eslint-plugin-react": "7.35.0",
|
"eslint-plugin-react": "7.35.0",
|
||||||
@ -93,16 +93,16 @@
|
|||||||
"eslint-plugin-storybook": "0.8.0",
|
"eslint-plugin-storybook": "0.8.0",
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
"jest-environment-jsdom": "29.7.0",
|
"jest-environment-jsdom": "29.7.0",
|
||||||
"knip": "5.27.2",
|
"knip": "5.27.4",
|
||||||
"lint-staged": "15.2.9",
|
"lint-staged": "15.2.9",
|
||||||
"prettier": "3.3.3",
|
"prettier": "3.3.3",
|
||||||
"puppeteer": "23.1.0",
|
"puppeteer": "23.1.1",
|
||||||
"react-is": "18.3.1",
|
"react-is": "18.3.1",
|
||||||
"storybook": "8.2.9",
|
"storybook": "8.2.9",
|
||||||
"ts-node": "10.9.2",
|
"ts-node": "10.9.2",
|
||||||
"typescript": "5.5.4",
|
"typescript": "5.5.4",
|
||||||
"vite": "5.4.1",
|
"vite": "5.4.2",
|
||||||
"vitest": "2.0.5",
|
"vitest": "2.0.5",
|
||||||
"npm-check-updates": "^17.0.6"
|
"npm-check-updates": "^17.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
front2/src/components/DisplayTrack.tsx
Normal file
42
front2/src/components/DisplayTrack.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { Flex, Text } from '@chakra-ui/react';
|
||||||
|
import { LuMusic2 } from 'react-icons/lu';
|
||||||
|
|
||||||
|
import { Track } from '@/back-api';
|
||||||
|
import { Covers } from '@/components/Cover';
|
||||||
|
|
||||||
|
export type DisplayTrackProps = {
|
||||||
|
track: Track;
|
||||||
|
};
|
||||||
|
export const DisplayTrack = ({ track }: DisplayTrackProps) => {
|
||||||
|
return (
|
||||||
|
<Flex direction="row" width="full" height="full">
|
||||||
|
<Covers
|
||||||
|
data={track?.covers}
|
||||||
|
size="50"
|
||||||
|
height="full"
|
||||||
|
iconEmpty={<LuMusic2 size="50" height="full" />}
|
||||||
|
/>
|
||||||
|
<Flex
|
||||||
|
direction="column"
|
||||||
|
width="full"
|
||||||
|
height="full"
|
||||||
|
paddingLeft="5px"
|
||||||
|
overflowX="hidden"
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
as="span"
|
||||||
|
align="left"
|
||||||
|
fontSize="20px"
|
||||||
|
fontWeight="bold"
|
||||||
|
userSelect="none"
|
||||||
|
marginRight="auto"
|
||||||
|
overflow="hidden"
|
||||||
|
noOfLines={[1, 2]}
|
||||||
|
marginY="auto"
|
||||||
|
>
|
||||||
|
[{track.track}] {track.name}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
13
front2/src/components/EmptyEnd.tsx
Normal file
13
front2/src/components/EmptyEnd.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
export const EmptyEnd = () => {
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
width="full"
|
||||||
|
height="25%"
|
||||||
|
minHeight="25%"
|
||||||
|
borderWidth="1px"
|
||||||
|
borderColor="red"
|
||||||
|
></Box>
|
||||||
|
);
|
||||||
|
};
|
62
front2/src/components/album/DisplayAlbum.tsx
Normal file
62
front2/src/components/album/DisplayAlbum.tsx
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { Flex, Text } from '@chakra-ui/react';
|
||||||
|
import { LuDisc3 } from 'react-icons/lu';
|
||||||
|
|
||||||
|
import { Album } from '@/back-api';
|
||||||
|
import { Covers } from '@/components/Cover';
|
||||||
|
import { useCountTracksWithAlbumId } from '@/service/Track';
|
||||||
|
|
||||||
|
export type DisplayAlbumProps = {
|
||||||
|
dataAlbum?: Album;
|
||||||
|
};
|
||||||
|
export const DisplayAlbum = ({ dataAlbum }: DisplayAlbumProps) => {
|
||||||
|
const { countTracksOfAnAlbum } = useCountTracksWithAlbumId(dataAlbum?.id);
|
||||||
|
if (!dataAlbum) {
|
||||||
|
return (
|
||||||
|
<Flex direction="row" width="full" height="full">
|
||||||
|
Fail to retrieve Album Data.
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Flex direction="row" width="full" height="full">
|
||||||
|
<Covers
|
||||||
|
data={dataAlbum?.covers}
|
||||||
|
size="100"
|
||||||
|
height="full"
|
||||||
|
iconEmpty={<LuDisc3 size="100" height="full" />}
|
||||||
|
/>
|
||||||
|
<Flex
|
||||||
|
direction="column"
|
||||||
|
width="150px"
|
||||||
|
maxWidth="150px"
|
||||||
|
height="full"
|
||||||
|
paddingLeft="5px"
|
||||||
|
overflowX="hidden"
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
as="span"
|
||||||
|
align="left"
|
||||||
|
fontSize="20px"
|
||||||
|
fontWeight="bold"
|
||||||
|
userSelect="none"
|
||||||
|
marginRight="auto"
|
||||||
|
overflow="hidden"
|
||||||
|
noOfLines={[1, 2]}
|
||||||
|
>
|
||||||
|
{dataAlbum?.name}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
as="span"
|
||||||
|
align="left"
|
||||||
|
fontSize="15px"
|
||||||
|
userSelect="none"
|
||||||
|
marginRight="auto"
|
||||||
|
overflow="hidden"
|
||||||
|
noOfLines={1}
|
||||||
|
>
|
||||||
|
{countTracksOfAnAlbum} track{countTracksOfAnAlbum >= 1 && 's'}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
10
front2/src/components/album/DisplayAlbumId.tsx
Normal file
10
front2/src/components/album/DisplayAlbumId.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { DisplayAlbum } from '@/components/album/DisplayAlbum';
|
||||||
|
import { useSpecificAlbum } from '@/service/Album';
|
||||||
|
|
||||||
|
export type DisplayAlbumIdProps = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
export const DisplayAlbumId = ({ id }: DisplayAlbumIdProps) => {
|
||||||
|
const { dataAlbum } = useSpecificAlbum(id);
|
||||||
|
return <DisplayAlbum dataAlbum={dataAlbum} />;
|
||||||
|
};
|
@ -8,6 +8,7 @@ import {
|
|||||||
import { AudioPlayer } from '@/components/AudioPlayer';
|
import { AudioPlayer } from '@/components/AudioPlayer';
|
||||||
import { Error404 } from '@/errors';
|
import { Error404 } from '@/errors';
|
||||||
import { ErrorBoundary } from '@/errors/ErrorBoundary';
|
import { ErrorBoundary } from '@/errors/ErrorBoundary';
|
||||||
|
import { AlbumRoutes } from '@/scene/album/AlbumRoutes';
|
||||||
import { ArtistRoutes } from '@/scene/artist/ArtistRoutes';
|
import { ArtistRoutes } from '@/scene/artist/ArtistRoutes';
|
||||||
import { HomePage } from '@/scene/home/HomePage';
|
import { HomePage } from '@/scene/home/HomePage';
|
||||||
import { SSORoutes } from '@/scene/sso/SSORoutes';
|
import { SSORoutes } from '@/scene/sso/SSORoutes';
|
||||||
@ -24,6 +25,7 @@ export const App = () => {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<HomePage />} />
|
<Route path="/" element={<HomePage />} />
|
||||||
<Route path="artist/*" element={<ArtistRoutes />} />
|
<Route path="artist/*" element={<ArtistRoutes />} />
|
||||||
|
<Route path="album/*" element={<AlbumRoutes />} />
|
||||||
<Route path="sso/*" element={<SSORoutes />} />
|
<Route path="sso/*" element={<SSORoutes />} />
|
||||||
<Route path="*" element={<Error404 />} />
|
<Route path="*" element={<Error404 />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
106
front2/src/scene/album/AlbumDetailPage.tsx
Normal file
106
front2/src/scene/album/AlbumDetailPage.tsx
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import { Box, Flex, Text } from '@chakra-ui/react';
|
||||||
|
import { LuDisc3 } from 'react-icons/lu';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { Covers } from '@/components/Cover';
|
||||||
|
import { DisplayTrack } from '@/components/DisplayTrack';
|
||||||
|
import { EmptyEnd } from '@/components/EmptyEnd';
|
||||||
|
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||||
|
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||||
|
import { TopBar } from '@/components/TopBar/TopBar';
|
||||||
|
import { useActivePlaylistService } from '@/service/ActivePlaylist';
|
||||||
|
import { useSpecificAlbum } from '@/service/Album';
|
||||||
|
import { useTracksOfAnAlbum } from '@/service/Track';
|
||||||
|
import { useThemeMode } from '@/utils/theme-tools';
|
||||||
|
|
||||||
|
export const AlbumDetailPage = () => {
|
||||||
|
const { albumId } = useParams();
|
||||||
|
const albumIdInt = albumId ? parseInt(albumId, 10) : undefined;
|
||||||
|
const { mode } = useThemeMode();
|
||||||
|
const { playInList } = useActivePlaylistService();
|
||||||
|
const { dataAlbum } = useSpecificAlbum(albumIdInt);
|
||||||
|
const { tracksOnAnAlbum } = useTracksOfAnAlbum(albumIdInt);
|
||||||
|
const onSelectItem = (trackId: number) => {
|
||||||
|
//navigate(`/artist/${artistIdInt}/album/${albumId}`);
|
||||||
|
let currentPlay = 0;
|
||||||
|
const listTrackId: number[] = [];
|
||||||
|
for (let iii = 0; iii < tracksOnAnAlbum.length; iii++) {
|
||||||
|
listTrackId.push(tracksOnAnAlbum[iii].id);
|
||||||
|
if (tracksOnAnAlbum[iii].id === trackId) {
|
||||||
|
currentPlay = iii;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playInList(currentPlay, listTrackId);
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`dataAlbum = ${JSON.stringify(dataAlbum, null, 2)}`);
|
||||||
|
if (!dataAlbum) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TopBar />
|
||||||
|
<PageLayoutInfoCenter>
|
||||||
|
Fail to load artist id: {albumId}
|
||||||
|
</PageLayoutInfoCenter>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TopBar />
|
||||||
|
<PageLayout>
|
||||||
|
<Flex
|
||||||
|
direction="row"
|
||||||
|
width="80%"
|
||||||
|
marginX="auto"
|
||||||
|
padding="10px"
|
||||||
|
gap="10px"
|
||||||
|
>
|
||||||
|
<Covers
|
||||||
|
data={dataAlbum?.covers}
|
||||||
|
iconEmpty={<LuDisc3 size="100" height="full" />}
|
||||||
|
/>
|
||||||
|
<Flex direction="column" width="80%" marginRight="auto">
|
||||||
|
<Text fontSize="24px" fontWeight="bold">
|
||||||
|
{dataAlbum?.name}
|
||||||
|
</Text>
|
||||||
|
{dataAlbum?.description && (
|
||||||
|
<Text>Description: {dataAlbum?.description}</Text>
|
||||||
|
)}
|
||||||
|
{dataAlbum?.publication && (
|
||||||
|
<Text>first name: {dataAlbum?.publication}</Text>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex
|
||||||
|
direction="column"
|
||||||
|
gap="20px"
|
||||||
|
marginX="auto"
|
||||||
|
padding="20px"
|
||||||
|
width="80%"
|
||||||
|
>
|
||||||
|
{tracksOnAnAlbum?.map((data) => (
|
||||||
|
<Box
|
||||||
|
minWidth="100%"
|
||||||
|
height="60px"
|
||||||
|
border="1px"
|
||||||
|
borderColor="brand.900"
|
||||||
|
backgroundColor={mode('#FFFFFF88', '#00000088')}
|
||||||
|
key={data.id}
|
||||||
|
padding="5px"
|
||||||
|
as="button"
|
||||||
|
_hover={{
|
||||||
|
boxShadow: 'outline-over',
|
||||||
|
bgColor: mode('#FFFFFFF7', '#000000F7'),
|
||||||
|
}}
|
||||||
|
onClick={() => onSelectItem(data.id)}
|
||||||
|
>
|
||||||
|
<DisplayTrack track={data} />
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
<EmptyEnd />
|
||||||
|
</Flex>
|
||||||
|
</PageLayout>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
16
front2/src/scene/album/AlbumRoutes.tsx
Normal file
16
front2/src/scene/album/AlbumRoutes.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { Error404 } from '@/errors';
|
||||||
|
import { AlbumDetailPage } from '@/scene/album/AlbumDetailPage';
|
||||||
|
import { AlbumsPage } from '@/scene/album/AlbumsPage';
|
||||||
|
|
||||||
|
export const AlbumRoutes = () => {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<Navigate to="all" replace />} />
|
||||||
|
<Route path="all" element={<AlbumsPage />} />
|
||||||
|
<Route path=":albumId" element={<AlbumDetailPage />} />
|
||||||
|
<Route path="*" element={<Error404 />} />
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
};
|
57
front2/src/scene/album/AlbumsPage.tsx
Normal file
57
front2/src/scene/album/AlbumsPage.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { Text, Wrap, WrapItem } from '@chakra-ui/react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||||
|
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||||
|
import { TopBar } from '@/components/TopBar/TopBar';
|
||||||
|
import { DisplayAlbum } from '@/components/album/DisplayAlbum';
|
||||||
|
import { useAlbumService } from '@/service/Album';
|
||||||
|
import { useThemeMode } from '@/utils/theme-tools';
|
||||||
|
|
||||||
|
export const AlbumsPage = () => {
|
||||||
|
const { store } = useAlbumService();
|
||||||
|
const { mode } = useThemeMode();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const onSelectItem = (albumId: number) => {
|
||||||
|
navigate(`/album/${albumId}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (store.isLoading) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TopBar />
|
||||||
|
<PageLayoutInfoCenter>No Album available</PageLayoutInfoCenter>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TopBar />
|
||||||
|
<PageLayout>
|
||||||
|
<Text>All Albums:</Text>
|
||||||
|
|
||||||
|
<Wrap spacing="20px" marginX="auto" padding="20px" justify="center">
|
||||||
|
{store.data?.map((data) => (
|
||||||
|
<WrapItem
|
||||||
|
width="270px"
|
||||||
|
height="120px"
|
||||||
|
border="1px"
|
||||||
|
borderColor="brand.900"
|
||||||
|
backgroundColor={mode('#FFFFFF88', '#00000088')}
|
||||||
|
key={data.id}
|
||||||
|
padding="5px"
|
||||||
|
as="button"
|
||||||
|
_hover={{
|
||||||
|
boxShadow: 'outline-over',
|
||||||
|
bgColor: mode('#FFFFFFF7', '#000000F7'),
|
||||||
|
}}
|
||||||
|
onClick={() => onSelectItem(data.id)}
|
||||||
|
>
|
||||||
|
<DisplayAlbum dataAlbum={data} />
|
||||||
|
</WrapItem>
|
||||||
|
))}
|
||||||
|
</Wrap>
|
||||||
|
</PageLayout>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -1,66 +1,19 @@
|
|||||||
import { Box, Flex, Text, Wrap, WrapItem } from '@chakra-ui/react';
|
import { Box, Flex, Text } from '@chakra-ui/react';
|
||||||
import { LuDisc3, LuFileAudio, LuMusic2, LuUser } from 'react-icons/lu';
|
import { LuDisc3, LuUser } from 'react-icons/lu';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { Album, Artist, Track } from '@/back-api';
|
|
||||||
import { Covers } from '@/components/Cover';
|
import { Covers } from '@/components/Cover';
|
||||||
|
import { DisplayTrack } from '@/components/DisplayTrack';
|
||||||
|
import { EmptyEnd } from '@/components/EmptyEnd';
|
||||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||||
import { TopBar } from '@/components/TopBar/TopBar';
|
import { TopBar } from '@/components/TopBar/TopBar';
|
||||||
import { useActivePlaylistService } from '@/service/ActivePlaylist';
|
import { useActivePlaylistService } from '@/service/ActivePlaylist';
|
||||||
import { useSpecificAlbum } from '@/service/Album';
|
import { useSpecificAlbum } from '@/service/Album';
|
||||||
import { useArtistService, useSpecificArtist } from '@/service/Artist';
|
import { useSpecificArtist } from '@/service/Artist';
|
||||||
import { useAlbumIdsOfAnArtist, useTracksOfAnAlbum } from '@/service/Track';
|
import { useTracksOfAnAlbum } from '@/service/Track';
|
||||||
import { useThemeMode } from '@/utils/theme-tools';
|
import { useThemeMode } from '@/utils/theme-tools';
|
||||||
|
|
||||||
export type DisplayTrackProps = {
|
|
||||||
track: Track;
|
|
||||||
};
|
|
||||||
export const DisplayTrack = ({ track }: DisplayTrackProps) => {
|
|
||||||
return (
|
|
||||||
<Flex direction="row" width="full" height="full">
|
|
||||||
<Covers
|
|
||||||
data={track?.covers}
|
|
||||||
size="50"
|
|
||||||
height="full"
|
|
||||||
iconEmpty={<LuMusic2 size="50" height="full" />}
|
|
||||||
/>
|
|
||||||
<Flex
|
|
||||||
direction="column"
|
|
||||||
width="full"
|
|
||||||
height="full"
|
|
||||||
paddingLeft="5px"
|
|
||||||
overflowX="hidden"
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
as="span"
|
|
||||||
align="left"
|
|
||||||
fontSize="20px"
|
|
||||||
fontWeight="bold"
|
|
||||||
userSelect="none"
|
|
||||||
marginRight="auto"
|
|
||||||
overflow="hidden"
|
|
||||||
noOfLines={[1, 2]}
|
|
||||||
marginY="auto"
|
|
||||||
>
|
|
||||||
[{track.track}] {track.name}
|
|
||||||
</Text>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export const EmptyEnd = () => {
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
width="full"
|
|
||||||
height="25%"
|
|
||||||
minHeight="25%"
|
|
||||||
borderWidth="1px"
|
|
||||||
borderColor="red"
|
|
||||||
></Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ArtistAlbumDetailPage = () => {
|
export const ArtistAlbumDetailPage = () => {
|
||||||
const { artistId, albumId } = useParams();
|
const { artistId, albumId } = useParams();
|
||||||
const artistIdInt = artistId ? parseInt(artistId, 10) : undefined;
|
const artistIdInt = artistId ? parseInt(artistId, 10) : undefined;
|
||||||
@ -85,12 +38,14 @@ export const ArtistAlbumDetailPage = () => {
|
|||||||
|
|
||||||
console.log(`dataAlbum = ${JSON.stringify(dataAlbum, null, 2)}`);
|
console.log(`dataAlbum = ${JSON.stringify(dataAlbum, null, 2)}`);
|
||||||
if (!dataAlbum) {
|
if (!dataAlbum) {
|
||||||
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar />
|
<TopBar />
|
||||||
<PageLayoutInfoCenter>
|
<PageLayoutInfoCenter>
|
||||||
Fail to load artist id: {artistId}
|
Fail to load artist id: {artistId}
|
||||||
</PageLayoutInfoCenter>
|
</PageLayoutInfoCenter>
|
||||||
</>;
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,55 +1,16 @@
|
|||||||
import { Flex, Text, Wrap, WrapItem } from '@chakra-ui/react';
|
import { Flex, Text, Wrap, WrapItem } from '@chakra-ui/react';
|
||||||
import { LuDisc3, LuUser } from 'react-icons/lu';
|
import { LuUser } from 'react-icons/lu';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { Album, Artist } from '@/back-api';
|
|
||||||
import { Covers } from '@/components/Cover';
|
import { Covers } from '@/components/Cover';
|
||||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||||
import { TopBar } from '@/components/TopBar/TopBar';
|
import { TopBar } from '@/components/TopBar/TopBar';
|
||||||
import { useSpecificAlbum } from '@/service/Album';
|
import { DisplayAlbumId } from '@/components/album/DisplayAlbumId';
|
||||||
import { useArtistService, useSpecificArtist } from '@/service/Artist';
|
import { useSpecificArtist } from '@/service/Artist';
|
||||||
import { useAlbumIdsOfAnArtist } from '@/service/Track';
|
import { useAlbumIdsOfAnArtist } from '@/service/Track';
|
||||||
import { useThemeMode } from '@/utils/theme-tools';
|
import { useThemeMode } from '@/utils/theme-tools';
|
||||||
|
|
||||||
export type DisplayAlbumProps = {
|
|
||||||
id: number;
|
|
||||||
};
|
|
||||||
export const DisplayAlbum = ({ id }: DisplayAlbumProps) => {
|
|
||||||
const { dataAlbum } = useSpecificAlbum(id);
|
|
||||||
return (
|
|
||||||
<Flex direction="row" width="full" height="full">
|
|
||||||
<Covers
|
|
||||||
data={dataAlbum?.covers}
|
|
||||||
size="100"
|
|
||||||
height="full"
|
|
||||||
iconEmpty={<LuDisc3 size="100" height="full" />}
|
|
||||||
/>
|
|
||||||
<Flex
|
|
||||||
direction="column"
|
|
||||||
width="150px"
|
|
||||||
maxWidth="150px"
|
|
||||||
height="full"
|
|
||||||
paddingLeft="5px"
|
|
||||||
overflowX="hidden"
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
as="span"
|
|
||||||
align="left"
|
|
||||||
fontSize="20px"
|
|
||||||
fontWeight="bold"
|
|
||||||
userSelect="none"
|
|
||||||
marginRight="auto"
|
|
||||||
overflow="hidden"
|
|
||||||
noOfLines={[1, 2]}
|
|
||||||
>
|
|
||||||
{dataAlbum?.name}
|
|
||||||
</Text>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ArtistDetailPage = () => {
|
export const ArtistDetailPage = () => {
|
||||||
const { artistId } = useParams();
|
const { artistId } = useParams();
|
||||||
const artistIdInt = artistId ? parseInt(artistId, 10) : undefined;
|
const artistIdInt = artistId ? parseInt(artistId, 10) : undefined;
|
||||||
@ -62,12 +23,14 @@ export const ArtistDetailPage = () => {
|
|||||||
const { albumIdsOfAnArtist } = useAlbumIdsOfAnArtist(artistIdInt);
|
const { albumIdsOfAnArtist } = useAlbumIdsOfAnArtist(artistIdInt);
|
||||||
|
|
||||||
if (!dataArtist) {
|
if (!dataArtist) {
|
||||||
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar />
|
<TopBar />
|
||||||
<PageLayoutInfoCenter>
|
<PageLayoutInfoCenter>
|
||||||
Fail to load artist id: {artistId}
|
Fail to load artist id: {artistId}
|
||||||
</PageLayoutInfoCenter>
|
</PageLayoutInfoCenter>
|
||||||
</>;
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -116,7 +79,7 @@ export const ArtistDetailPage = () => {
|
|||||||
}}
|
}}
|
||||||
onClick={() => onSelectItem(data)}
|
onClick={() => onSelectItem(data)}
|
||||||
>
|
>
|
||||||
<DisplayAlbum id={data} key={data} />
|
<DisplayAlbumId id={data} key={data} />
|
||||||
</WrapItem>
|
</WrapItem>
|
||||||
))}
|
))}
|
||||||
</Wrap>
|
</Wrap>
|
||||||
|
@ -139,10 +139,10 @@ export const useTracksOfAnAlbum = (idAlbum?: number) => {
|
|||||||
* @param AlbumId - Id of the album.
|
* @param AlbumId - Id of the album.
|
||||||
* @returns The number of element present in this season
|
* @returns The number of element present in this season
|
||||||
*/
|
*/
|
||||||
export const useCountTracksWithAlbumId = (albumId: number) => {
|
export const useCountTracksWithAlbumId = (albumId?: number) => {
|
||||||
const { tracksOnAnAlbum } = useTracksOfAnAlbum(albumId);
|
const { tracksOnAnAlbum } = useTracksOfAnAlbum(albumId);
|
||||||
const countTracksOnAnArtist = tracksOnAnAlbum.length;
|
const countTracksOfAnAlbum = tracksOnAnAlbum.length;
|
||||||
return { countTracksOnAnArtist };
|
return { countTracksOfAnAlbum };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user