fix/theme-playlists-performance #1

Merged
smedmunds merged 2 commits from fix/theme-playlists-performance into master 2026-10-12 11:21:30 -05:00
Showing only changes of commit bf761df56d - Show all commits

View File

@@ -2,7 +2,7 @@ import { Box, Group, LoadingOverlay, SimpleGrid, Stack, Text } from '@mantine/co
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { NoItemsFound, SettingsHeader } from 'components';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState, useMemo, useCallback } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { FiChevronRight } from 'react-icons/fi';
import { textClasses } from 'styles';
import type { Theme, ThemePlaylist } from 'types';
@@ -23,11 +23,13 @@ export function ThemePlaylists() {
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
const themePlaylists: ThemePlaylist[] = useMemo(() => {
return themePlaylistData?.filter(
(a: ThemePlaylist) =>
a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()) ||
a.name.includes('Time of Day'),
) || [];
return (
themePlaylistData?.filter(
(a: ThemePlaylist) =>
a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()) ||
a.name.includes('Time of Day'),
) || []
);
}, [themePlaylistData, debouncedSearch]);
const defaultPlaylist: ThemePlaylist = {
id: undefined,
@@ -42,10 +44,13 @@ export function ThemePlaylists() {
const { currentThemePlaylist, theme, isMobile } = useCommonHooks();
const [isLoading, setIsLoading] = useState(false);
const handleOpen = useCallback((playlist: ThemePlaylist) => {
setSelectedPlaylist(playlist);
open();
}, [open]);
const handleOpen = useCallback(
(playlist: ThemePlaylist) => {
setSelectedPlaylist(playlist);
open();
},
[open],
);
const handleClose = useCallback(() => {
setSelectedPlaylist(defaultPlaylist);
@@ -67,17 +72,26 @@ export function ThemePlaylists() {
}
}, [debouncedSearch, searchValue]);
const allThemesIds = useMemo(() =>
allThemeData?.map((a: Theme) => a.id) ?? [],
[allThemeData]);
const allThemesIds = useMemo(
() => allThemeData?.map((a: Theme) => a.id) ?? [],
[allThemeData],
);
const backgroundsThemes = useMemo(() =>
allThemeData?.filter((a: any) => !a.backgroundImage.toLowerCase().includes('none')) ?? [],
[allThemeData]);
const backgroundsThemes = useMemo(
() =>
allThemeData?.filter(
(a: any) => !a.backgroundImage.toLowerCase().includes('none'),
) ?? [],
[allThemeData],
);
const noBackgroundsThemes = useMemo(() =>
allThemeData?.filter((a: any) => a.backgroundImage.toLowerCase().includes('none')) ?? [],
[allThemeData]);
const noBackgroundsThemes = useMemo(
() =>
allThemeData?.filter((a: any) =>
a.backgroundImage.toLowerCase().includes('none'),
) ?? [],
[allThemeData],
);
const timeOfDayPlaylist = useMemo(() => {
const found = themePlaylists?.find((a: ThemePlaylist) => a.name === 'Time of Day');
@@ -89,26 +103,35 @@ export function ThemePlaylists() {
};
}, [themePlaylists]);
const allStack = useMemo(() => ({
id: undefined,
name: 'All',
default: 1,
themeList: `[${allThemesIds.join(',')}]`,
}), [allThemesIds]);
const allStack = useMemo(
() => ({
id: undefined,
name: 'All',
default: 1,
themeList: `[${allThemesIds.join(',')}]`,
}),
[allThemesIds],
);
const backgroundsStack = useMemo(() => ({
id: undefined,
name: 'Backgrounds',
default: 1,
themeList: `[${backgroundsThemes.map((a: Theme) => a.id).join(',')}]`,
}), [backgroundsThemes]);
const backgroundsStack = useMemo(
() => ({
id: undefined,
name: 'Backgrounds',
default: 1,
themeList: `[${backgroundsThemes.map((a: Theme) => a.id).join(',')}]`,
}),
[backgroundsThemes],
);
const noBackgroundsStack = useMemo(() => ({
id: undefined,
name: 'No Backgrounds',
default: 1,
themeList: `[${noBackgroundsThemes.map((a: Theme) => a.id).join(',')}]`,
}), [noBackgroundsThemes]);
const noBackgroundsStack = useMemo(
() => ({
id: undefined,
name: 'No Backgrounds',
default: 1,
themeList: `[${noBackgroundsThemes.map((a: Theme) => a.id).join(',')}]`,
}),
[noBackgroundsThemes],
);
return (
<Stack>
@@ -153,7 +176,7 @@ export function ThemePlaylists() {
/>
{allThemeData && (
<>
<Group justify='center' align='center' pos={'relative'}>
<Stack w={'100%'} justify='center' align='center' pos={'relative'}>
<Text
p={0}
className={textClasses.settingsSubTitle}
@@ -161,169 +184,171 @@ export function ThemePlaylists() {
>
Defaults
</Text>
</Group>
<Group justify='center' align='center' pos={'relative'}>
<Group pos={'relative'}>
{'All' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color: 'var(--mantine-color-background-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={allStack}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
</Group>
<Group pos={'relative'}>
{'Backgrounds' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={backgroundsStack}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
<Group pos={'relative'}>
{'No Backgrounds' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={noBackgroundsStack}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
<Group pos={'relative'}>
{'Time of Day' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={timeOfDayPlaylist}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
<Group justify='center' align='center' pos={'relative'}>
<Text
p={0}
className={textClasses.settingsSubTitle}
classNames={textClasses}
>
User Made
</Text>
</Group>
<Group
justify='center'
align='center'
pos={'relative'}
mb={isMobile ? '6rem' : undefined}
>
{themePlaylists.length > 1 ? (
<SimpleGrid cols={isMobile ? 1 : 4}>
{themePlaylists
.filter((playlist: ThemePlaylist) => playlist.default === 0)
.sort((a: ThemePlaylist, b: ThemePlaylist) =>
a.name.toLocaleLowerCase() > b.name.toLocaleLowerCase() ? 1 : -1,
)
.map((cardPlaylist: ThemePlaylist) => {
return (
<Group key={cardPlaylist.name} pos={'relative'}>
{cardPlaylist.name === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-primary-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={cardPlaylist}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
);
})}
</SimpleGrid>
) : (
<Group w={'100%'} style={{ display: 'flex', justifyContent: 'center' }}>
<NoItemsFound />
<Group>
<Group pos={'relative'}>
{'All' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color: 'var(--mantine-color-background-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={allStack}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
)}
</Group>
<Group pos={'relative'}>
{'Backgrounds' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={backgroundsStack}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
<Group pos={'relative'}>
{'No Backgrounds' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={noBackgroundsStack}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
<Group pos={'relative'}>
{'Time of Day' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={timeOfDayPlaylist}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
</Group>
</Stack>
<Stack w={'100%'} justify='center' align='center' pos={'relative'}>
<Group justify='center' align='center' pos={'relative'}>
<Text
p={0}
className={textClasses.settingsSubTitle}
classNames={textClasses}
>
User Made
</Text>
</Group>
<Group
justify='center'
align='center'
pos={'relative'}
mb={isMobile ? '6rem' : undefined}
>
{themePlaylists.length > 1 ? (
<SimpleGrid cols={isMobile ? 1 : 4}>
{themePlaylists
.filter((playlist: ThemePlaylist) => playlist.default === 0)
.sort((a: ThemePlaylist, b: ThemePlaylist) =>
a.name.toLocaleLowerCase() > b.name.toLocaleLowerCase() ? 1 : -1,
)
.map((cardPlaylist: ThemePlaylist) => {
return (
<Group key={cardPlaylist.name} pos={'relative'}>
{cardPlaylist.name === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2rem',
fontWeight: 'bold',
borderRadius: '50%',
backgroundColor: 'var(--mantine-color-border-0)',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-primary-0)',
}}
/>
)}
<Box>
<ThemePlaylistStack
cardPlaylist={cardPlaylist}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
);
})}
</SimpleGrid>
) : (
<Group w={'100%'} style={{ display: 'flex', justifyContent: 'center' }}>
<NoItemsFound />
</Group>
)}
</Group>
</Stack>
</>
)}
</Stack>