import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query'; import { shuffle } from 'lodash'; import { memo, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { generatePath, Link } from 'react-router'; import styles from './featured-genres.module.css'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { genresQueries } from '/@/renderer/features/genres/api/genres-api'; import { useIsPlayerFetching, usePlayer } from '/@/renderer/features/player/context/player-context'; import { PlayButton } from '/@/renderer/features/shared/components/play-button'; import { useContainerQuery } from '/@/renderer/hooks'; import { AppRoute } from '/@/renderer/router/routes'; import { useCurrentServer, useCurrentServerId } from '/@/renderer/store'; import { Button } from '/@/shared/components/button/button'; import { Group } from '/@/shared/components/group/group'; import { TextTitle } from '/@/shared/components/text-title/text-title'; import { Genre, GenreListSort, Played, SortOrder } from '/@/shared/types/domain-types'; import { Play } from '/@/shared/types/types'; import { stringToColor } from '/@/shared/utils/string-to-color'; function getGenresToShow(breakpoints: { isLargerThanLg: boolean; isLargerThanMd: boolean; isLargerThanSm: boolean; isLargerThanXl: boolean; isLargerThanXxl: boolean; isLargerThanXxxl: boolean; }) { if (breakpoints.isLargerThanXxxl) { return 18; } if (breakpoints.isLargerThanXxl) { return 15; } if (breakpoints.isLargerThanXl) { return 12; } if (breakpoints.isLargerThanLg) { return 12; } if (breakpoints.isLargerThanMd) { return 12; } if (breakpoints.isLargerThanSm) { return 8; } return 6; } export const FeaturedGenres = () => { const { t } = useTranslation(); const server = useCurrentServer(); const { ref, ...cq } = useContainerQuery({ lg: 900, md: 600, sm: 360, }); const genresQuery = useSuspenseQuery({ ...genresQueries.list({ query: { limit: -1, sortBy: GenreListSort.NAME, sortOrder: SortOrder.ASC, startIndex: 0, }, serverId: server?.id, }), queryKey: [server.id, 'home', 'featured-genres'], }); const randomGenres = useMemo(() => { if (!genresQuery.data?.items) return []; return shuffle(genresQuery.data.items); }, [genresQuery.data]); const genresToShow = useMemo(() => { return getGenresToShow({ isLargerThanLg: cq.isLg, isLargerThanMd: cq.isMd, isLargerThanSm: cq.isSm, isLargerThanXl: cq.isXl, isLargerThanXxl: cq.is2xl, isLargerThanXxxl: cq.is3xl, }); }, [cq.isLg, cq.isMd, cq.isSm, cq.isXl, cq.is2xl, cq.is3xl]); const visibleGenres = useMemo(() => { return randomGenres.slice(0, genresToShow); }, [randomGenres, genresToShow]); const genresWithColors = useMemo(() => { if (!visibleGenres) return []; return visibleGenres.map((genre: Genre) => { const { color, isLight } = stringToColor(genre.name); const path = generatePath(AppRoute.LIBRARY_GENRES_DETAIL, { genreId: genre.id }); return { ...genre, color, isLight, path, }; }); }, [visibleGenres]); return (