karusic/front/src/scene/artist/ArtistsPage.tsx
2025-05-01 23:10:05 +02:00

139 lines
4.4 KiB
TypeScript

import { useState } from 'react';
import { Button, Flex, HStack, Span, Text, Tooltip } from '@chakra-ui/react';
import { LuUser } from 'react-icons/lu';
import { MdOutlineForkRight } from 'react-icons/md';
import { useNavigate } from 'react-router-dom';
import { Artist, ObjectId, Track } from '@/back-api';
import { Covers } from '@/components/Cover';
import { EmptyEnd } from '@/components/EmptyEnd';
import { PageLayout } from '@/components/Layout/PageLayout';
import { SearchInput } from '@/components/SearchInput';
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
import { useColorModeValue } from '@/components/ui/color-mode';
import {
BASE_WRAP_HEIGHT,
BASE_WRAP_ICON_SIZE,
BASE_WRAP_SPACING,
BASE_WRAP_WIDTH,
} from '@/constants/genericSpacing';
import { useActivePlaylistService } from '@/service/ActivePlaylist';
import { useOrderedArtists } from '@/service/Artist';
import { useTrackService } from '@/service/Track';
import { shuffleArray } from '@/utils/arrayTools';
import { DataTools, TypeCheck } from '@/utils/data-tools';
const LIMIT_RANDOM_VALUES = 25;
export const ArtistsPage = () => {
const [filterName, setFilterName] = useState<string | undefined>(undefined);
const navigate = useNavigate();
const { playInList } = useActivePlaylistService();
const onSelectItem = (data: Artist) => {
navigate(`/artist/${data.oid}/`);
};
const { dataArtist } = useOrderedArtists(filterName);
const { store: trackStore } = useTrackService();
const onRandomPlay = () => {
const data = shuffleArray(dataArtist);
const playingList: ObjectId[] = [];
for (let i = 0; i < Math.min(data.length, LIMIT_RANDOM_VALUES); i++) {
const selectedArtist: Artist = data[i];
const listArtistTracks: Track[] = DataTools.getsWhere(
trackStore.data,
[
{
check: TypeCheck.CONTAINS,
key: 'artists',
value: selectedArtist.oid,
},
],
[]
);
if (listArtistTracks.length === 0) {
continue;
}
playingList.push(
listArtistTracks[Math.floor(Math.random() * listArtistTracks.length)]
.oid
);
}
playInList(0, playingList);
};
return (
<>
<TopBar title="All artists" titleLink="/home">
<SearchInput onChange={setFilterName} />
<Tooltip.Root aria-label="Random play">
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={onRandomPlay}>
<MdOutlineForkRight style={{ width: '100%', height: '100%' }} />
</Button>
</Tooltip.Root>
</TopBar>
<PageLayout>
<HStack
wrap="wrap"
gap={BASE_WRAP_SPACING}
marginX="auto"
padding="20px"
justify="center"
>
{dataArtist?.map((data) => (
<Flex
align="flex-start"
width={BASE_WRAP_WIDTH}
height={BASE_WRAP_HEIGHT}
border="1px"
borderColor="brand.900"
backgroundColor={useColorModeValue('#FFFFFF88', '#00000088')}
key={data.oid}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: useColorModeValue('#FFFFFFF7', '#000000F7'),
}}
onClick={() => onSelectItem(data)}
>
<Flex direction="row" width="full" height="full">
<Covers
data={data.covers}
size={BASE_WRAP_ICON_SIZE}
height="full"
iconEmpty={<LuUser />}
/>
<Flex
direction="column"
width="150px"
maxWidth="150px"
height="full"
paddingLeft="5px"
overflowX="hidden"
>
<Text
textAlign="left"
/*noOfLines={[1, 2]}*/
>
<Span
fontSize="20px"
fontWeight="bold"
userSelect="none"
marginRight="auto"
overflow="hidden"
>
{data.name}
</Span>
</Text>
</Flex>
</Flex>
</Flex>
))}
</HStack>
<EmptyEnd />
</PageLayout>
</>
);
};