Bugfixes and updates
This commit is contained in:
201
src/pages/homepage/components/SettingsButton/ThemingCard.tsx
Normal file
201
src/pages/homepage/components/SettingsButton/ThemingCard.tsx
Normal file
@@ -0,0 +1,201 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
type ComboboxItem,
|
||||
Group,
|
||||
Menu,
|
||||
Select,
|
||||
Stack,
|
||||
Text,
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { useCommonHooks, useQueryAPI } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { FaDice } from 'react-icons/fa';
|
||||
import { FiShuffle } from 'react-icons/fi';
|
||||
import { actionIconClasses, selectClasses, stackClasses } from 'styles';
|
||||
import type { Theme, ThemePlaylist } from 'types';
|
||||
|
||||
function ThemingCard() {
|
||||
const { data: themePlaylistData } = useQueryAPI({
|
||||
endpoint: 'api/themePlaylists',
|
||||
});
|
||||
const { data: allThemeData, isFetched: allThemeDataIsFetched } = useQueryAPI({
|
||||
endpoint: 'api/themes',
|
||||
});
|
||||
const [allThemes, setAllThemes] = useState<Theme[]>([]);
|
||||
useEffect(() => {
|
||||
if (allThemeData && allThemeDataIsFetched) {
|
||||
setAllThemes(allThemeData);
|
||||
}
|
||||
}, [allThemeData, allThemeDataIsFetched]);
|
||||
const {
|
||||
currentTheme,
|
||||
setCurrentTheme,
|
||||
setThemeName,
|
||||
handleThemeChange,
|
||||
theme,
|
||||
currentThemePlaylist,
|
||||
setCurrentThemePlaylist,
|
||||
} = useCommonHooks();
|
||||
return (
|
||||
<Stack
|
||||
gap={0}
|
||||
align='center'
|
||||
className={stackClasses.menuStack}
|
||||
classNames={stackClasses}
|
||||
style={{ aspectRatio: '1/1' }}
|
||||
>
|
||||
<Menu.Label pb={'.25rem'}>Themes</Menu.Label>
|
||||
<Group mt={'-1.5rem'} mb={'-.25rem'} w={'95%'} justify='space-between'>
|
||||
<Tooltip
|
||||
label='Shuffle Themes'
|
||||
c={'var(--mantine-color-primary-0)'}
|
||||
bg={'var(--mantine-color-background-0)'}
|
||||
withArrow
|
||||
>
|
||||
<ActionIcon
|
||||
className={actionIconClasses.menuActions}
|
||||
classNames={actionIconClasses}
|
||||
disabled={currentThemePlaylist === 'Time of Day'}
|
||||
style={{
|
||||
backgroundColor:
|
||||
currentTheme === 'random'
|
||||
? `${theme?.searchColor === theme?.primaryColor ? theme.searchColor?.substring(0, 7) : theme.primaryColor?.substring(0, 7)}88`
|
||||
: 'transparent',
|
||||
color:
|
||||
currentTheme === 'random'
|
||||
? 'var(--mantine-color-accent-0)'
|
||||
: 'var(--mantine-color-primary-0)',
|
||||
}}
|
||||
onClick={() => {
|
||||
setCurrentTheme(currentTheme === 'random' ? theme.name : 'random');
|
||||
setCurrentThemePlaylist('All');
|
||||
}}
|
||||
>
|
||||
<FiShuffle />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
label='Random Theme'
|
||||
c={'var(--mantine-color-primary-0)'}
|
||||
bg={'var(--mantine-color-background-0)'}
|
||||
withArrow
|
||||
>
|
||||
<ActionIcon
|
||||
className={actionIconClasses.menuActions}
|
||||
classNames={actionIconClasses}
|
||||
style={{
|
||||
backgroundColor: 'transparent',
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
}}
|
||||
disabled={currentThemePlaylist === 'Time of Day'}
|
||||
onClick={() => {
|
||||
const themeList = JSON.parse(
|
||||
themePlaylistData?.find(
|
||||
(t: ThemePlaylist) => t?.name === currentThemePlaylist,
|
||||
)?.themeList ?? '[]',
|
||||
);
|
||||
if (themeList.length > 0) {
|
||||
const filteredThemes = allThemes.filter((t: Theme) =>
|
||||
themeList.includes(t.id),
|
||||
);
|
||||
handleThemeChange(filteredThemes, false);
|
||||
} else if (currentThemePlaylist === 'All') {
|
||||
handleThemeChange(allThemes, false);
|
||||
} else if (currentThemePlaylist === 'Backgrounds') {
|
||||
handleThemeChange(
|
||||
allThemes.filter(
|
||||
(a: any) => !a.backgroundImage.toLowerCase().includes('none'),
|
||||
),
|
||||
false,
|
||||
);
|
||||
} else if (currentThemePlaylist === 'No Backgrounds') {
|
||||
handleThemeChange(
|
||||
allThemes.filter((a: any) =>
|
||||
a.backgroundImage.toLowerCase().includes('none'),
|
||||
),
|
||||
false,
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<FaDice />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
<Text fw={'bold'} fz={'1.125rem'}>
|
||||
Currently:{' '}
|
||||
</Text>
|
||||
{theme.name}
|
||||
<Text fw={'bold'} fz={'1.125rem'}>
|
||||
Playlist:{' '}
|
||||
</Text>
|
||||
<Select
|
||||
labelProps={{ display: 'none' }}
|
||||
placeholder='Pick a playlist...'
|
||||
value={currentThemePlaylist}
|
||||
data={[
|
||||
{ value: 'All', label: 'All' },
|
||||
{
|
||||
value: 'Backgrounds',
|
||||
label: 'Backgrounds',
|
||||
disabled:
|
||||
allThemes.filter(
|
||||
(a: any) => !a.backgroundImage.toLowerCase().includes('none'),
|
||||
).length === 0,
|
||||
},
|
||||
{
|
||||
value: 'No Backgrounds',
|
||||
label: 'No Backgrounds',
|
||||
disabled:
|
||||
allThemes.filter((a: any) =>
|
||||
a.backgroundImage.toLowerCase().includes('none'),
|
||||
).length === 0,
|
||||
},
|
||||
...(themePlaylistData
|
||||
?.map((playlist: ThemePlaylist) => {
|
||||
return {
|
||||
value: playlist.name,
|
||||
label: playlist.name,
|
||||
disabled: JSON.parse(playlist.themeList).length === 0,
|
||||
};
|
||||
})
|
||||
.toSorted((a: ComboboxItem, b: ComboboxItem) =>
|
||||
a.label.localeCompare(b.label),
|
||||
) ?? []),
|
||||
]}
|
||||
w='92%'
|
||||
classNames={{
|
||||
root: selectClasses.menuSelectRoot,
|
||||
input: selectClasses.menuSelectInput,
|
||||
label: selectClasses.menuSelectLabel,
|
||||
options: selectClasses.menuSelectOptions,
|
||||
option: selectClasses.menuSelectOption,
|
||||
}}
|
||||
comboboxProps={{
|
||||
withinPortal: false,
|
||||
position: 'top',
|
||||
}}
|
||||
onChange={(_value, option: ComboboxItem) => {
|
||||
setCurrentThemePlaylist(option.value);
|
||||
if (option.value !== 'Time of Day') {
|
||||
setThemeName('random');
|
||||
} else {
|
||||
const themeList = JSON.parse(
|
||||
themePlaylistData.find((t: ThemePlaylist) => t.name === 'Time of Day')
|
||||
.themeList,
|
||||
);
|
||||
setThemeName(
|
||||
allThemeData.find(
|
||||
(t: Theme) =>
|
||||
t.id === Number(themeList[Math.floor(new Date().getHours() / 6)]),
|
||||
).name,
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
export default ThemingCard;
|
||||
Reference in New Issue
Block a user