139 lines
4.4 KiB
TypeScript
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>
|
|
</>
|
|
);
|
|
};
|