Theme updates and style fixes

This commit is contained in:
Sean Edmunds
2025-05-23 13:32:38 -05:00
parent ee69cc9d09
commit 79ebb1b9e9
16 changed files with 488 additions and 386 deletions

View File

@@ -88,6 +88,16 @@ function App() {
t.id === Number(themeList[Math.floor(new Date().getHours() / 6)]),
),
);
} 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,
);
} else {
const themeList = JSON.parse(
themePlaylists.find((t: ThemePlaylist) => t.name === currentThemePlaylist)

View File

@@ -189,7 +189,8 @@ function SettingsButton() {
<Group mt={'-1.5rem'} mb={'-.25rem'} w={'95%'} justify='space-between'>
<Tooltip
label='Shuffle Themes'
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
withArrow
>
<ActionIcon
@@ -217,7 +218,8 @@ function SettingsButton() {
</Tooltip>
<Tooltip
label='Random Theme'
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
withArrow
>
<ActionIcon

View File

@@ -25,12 +25,15 @@ function AppSettingsItem({
<Box pos={'relative'}>
{enabled === 0 && (
<Tooltip
label={<Text c={'var(--mantine-color-primary-0)'}>This app is disabled</Text>}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
label='This app is disabled.'
>
<ActionIcon
className={actionIconClasses.settingsTooltip}
classNames={actionIconClasses}
pos={'absolute'}
right={0}
size={'xl'}
variant='subtle'
style={{ zIndex: 1 }}

View File

@@ -2,7 +2,6 @@ import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd';
import {
Box,
Button,
Card,
type ComboboxItem,
type ComboboxLikeRenderOptionInput,
Divider,
@@ -281,142 +280,104 @@ const ApplicationSettings = () => {
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
{dragging ? (
<DragDropContext onDragEnd={onDragEnd}>
<Stack
mt={isMobile ? '9rem' : '6rem'}
mb={isMobile ? '6rem' : '1rem'}
w={'100%'}
align='center'
>
<Droppable droppableId={'groupList'}>
{(provided) => (
<Stack
w={'75%'}
align='center'
justify='center'
ref={provided.innerRef}
{...provided.droppableProps}
>
{applications?.map((app: Application) => (
<Draggable
key={app.id}
draggableId={`${app.id}`}
index={Number(app.index)}
>
{(provided) => (
<Box
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<Card
w={'400px'}
style={{
backgroundColor: 'var(--mantine-color-search-0)',
border: '1px solid var(--mantine-color-border-0)',
borderRadius: '8px',
}}
>
<Group gap={0} align='center' justify='space-between'>
<Stack gap={0}>
<Text c={'var(--mantine-color-accent-0)'} fz={14}>
Name
</Text>
<Text
p={4}
style={{
borderRadius: '4px',
paddingLeft: '8px',
color: 'var(--mantine-color-primary-0)',
backgroundColor: 'var(--mantine-color-search-0)',
}}
>
{app.name}
</Text>
</Stack>
<Stack gap={0}>
<Text c={'var(--mantine-color-accent-0)'} fz={14}>
Filter Name
</Text>
<Text
p={4}
style={{
borderRadius: '4px',
paddingLeft: '8px',
color: 'var(--mantine-color-primary-0)',
backgroundColor: 'var(--mantine-color-search-0)',
}}
>
{app.filterName}
</Text>
</Stack>
</Group>
</Card>
</Box>
)}
</Draggable>
))}
{provided.placeholder}
</Stack>
)}
</Droppable>
</Stack>
</DragDropContext>
) : (
<DragDropContext onDragEnd={onDragEnd}>
<Stack
mt={isMobile ? '9rem' : '6rem'}
mb={isMobile ? '6rem' : '1rem'}
w={'100%'}
align='center'
>
<Grid columns={18} w={'75%'}>
{applications.length > 0 ? (
applications?.map((application: Application) => (
<GridCol span={6} key={application.id}>
<Popover
withArrow
withOverlay
closeOnClickOutside={!isOpen}
classNames={popoverClasses}
>
<Popover.Target>
<Box
onClick={(e) => {
e.stopPropagation();
}}
>
<AppSettingsItem
url={application.url}
icon={application.icon}
name={application.name}
enabled={application.enabled}
allIcons={allIcons}
/>
</Box>
</Popover.Target>
<Popover.Dropdown w={isMobile ? '100%' : undefined}>
<DebouncedApplication
application={application}
setIsOpen={setIsOpen}
allIcons={allIcons}
/>
</Popover.Dropdown>
</Popover>
</GridCol>
))
) : (
<GridCol
w={'100%'}
span={18}
style={{ display: 'flex', justifyContent: 'center' }}
>
<NoItemsFound />
</GridCol>
)}
</Grid>
{applications.length > 0 ? (
<Droppable droppableId={'groupList'}>
{(provided) => (
<Grid
columns={18}
w={dragging ? '30%' : '75%'}
ref={provided.innerRef}
{...provided.droppableProps}
>
{applications?.map((application: Application, index: number) => (
<GridCol span={dragging ? 18 : 6} key={application.id}>
{dragging ? (
<Draggable
key={application.id}
draggableId={`${application.id}`}
index={Number(application.index)}
>
{(provided) => (
<Box
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<Box pos={'relative'} h={'100%'}>
<Text
style={{
color: 'var(--mantine-color-primary-0)',
zIndex: 1,
alignContent: 'center',
fontSize: '1.5em',
position: 'absolute',
right: 0,
paddingRight: '1rem',
height: '100%',
}}
>
#{index + 1}
</Text>
<AppSettingsItem
url={application.url}
icon={application.icon}
name={application.name}
enabled={application.enabled}
allIcons={allIcons}
/>
</Box>
</Box>
)}
</Draggable>
) : (
<Popover
withArrow
withOverlay
closeOnClickOutside={!isOpen}
classNames={popoverClasses}
>
<Popover.Target>
<Box
onClick={(e) => {
e.stopPropagation();
}}
>
<AppSettingsItem
url={application.url}
icon={application.icon}
name={application.name}
enabled={application.enabled}
allIcons={allIcons}
/>
</Box>
</Popover.Target>
<Popover.Dropdown w={isMobile ? '100%' : undefined}>
<DebouncedApplication
application={application}
setIsOpen={setIsOpen}
allIcons={allIcons}
/>
</Popover.Dropdown>
</Popover>
)}
</GridCol>
))}
{provided.placeholder}
</Grid>
)}
</Droppable>
) : (
<NoItemsFound />
)}
</Stack>
)}
</DragDropContext>
</Stack>
);
};

View File

@@ -72,7 +72,8 @@ function DebouncedApplication({
}
/>
<Tooltip
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
bd={'solid 1px var(--mantine-color-border-0)'}
label={'Delete'}
>
@@ -89,7 +90,8 @@ function DebouncedApplication({
</ActionIcon>
</Tooltip>
<Tooltip
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
bd={'solid 1px var(--mantine-color-border-0)'}
label={'Enabled'}
>

View File

@@ -60,7 +60,8 @@ function DebouncedBookmarkItem({
title='Delete Bookmark'
/>
<Tooltip
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
bd={'solid 1px var(--mantine-color-border-0)'}
label={'Delete'}
>

View File

@@ -168,7 +168,8 @@ function DebouncedGroupSettingsItem({
}}
/>
<Tooltip
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
bd={'solid 1px var(--mantine-color-border-0)'}
label={'Delete'}
>

View File

@@ -43,7 +43,8 @@ function DebouncedMessage({
}
/>
<Tooltip
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
bd={'solid 1px var(--mantine-color-border-0)'}
label={'Delete'}
>

View File

@@ -65,7 +65,8 @@ function DebouncedSearchProvider({
}
/>
<Tooltip
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
bd={'solid 1px var(--mantine-color-border-0)'}
label={'Delete'}
>

View File

@@ -10,6 +10,7 @@ import {
TextInput,
} from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { useState } from 'react';
import { FiHelpCircle, FiLoader, FiPlus } from 'react-icons/fi';
import {
actionIconClasses,
@@ -46,6 +47,7 @@ function SettingsHeader({
setIsLoading: (isLoading: boolean) => void;
}) {
const { isMobile } = useCommonHooks();
const [disabled, setDisabled] = useState(false);
return (
<Group
align='center'
@@ -119,6 +121,7 @@ function SettingsHeader({
</Group>
{searchValue !== undefined && (
<TextInput
disabled={disabled}
w={isMobile ? undefined : '35%'}
pos={isMobile ? undefined : 'absolute'}
className={textInputClasses.settingsItem}
@@ -156,6 +159,7 @@ function SettingsHeader({
top={isMobile ? '3.5rem' : undefined}
onChange={(e) => {
setDragging(e.target.checked);
setDisabled(e.target.checked);
}}
/>
)}

View File

@@ -197,7 +197,7 @@ function ThemeCard({
setShiftEdit(0);
}}
onClick={() => {
setShiftEdit(0);
handleOpen(cardTheme);
}}
gap={0}
style={{
@@ -216,9 +216,6 @@ function ThemeCard({
}}
>
<FiEdit
onClick={() => {
handleOpen(cardTheme);
}}
style={{
fontSize: '2em',
fontWeight: 'bold',
@@ -234,7 +231,15 @@ function ThemeCard({
setShiftShuffle(0);
}}
onClick={() => {
setShiftShuffle(0);
const themeList = JSON.parse(
themePlaylists?.find(
(t: ThemePlaylist) => t?.name === currentThemePlaylist,
)?.themeList ?? '[]',
);
const filteredThemes = allThemes.filter((t: Theme) =>
themeList.includes(t.id),
);
handleThemeChange(filteredThemes, false);
}}
gap={0}
style={{
@@ -254,17 +259,6 @@ function ThemeCard({
}}
>
<FiShuffle
onClick={() => {
const themeList = JSON.parse(
themePlaylists?.find(
(t: ThemePlaylist) => t?.name === currentThemePlaylist,
)?.themeList ?? '[]',
);
const filteredThemes = allThemes.filter((t: Theme) =>
themeList.includes(t.id),
);
handleThemeChange(filteredThemes, false);
}}
style={{
fontSize: '2em',
fontWeight: 'bold',

View File

@@ -8,9 +8,9 @@ import {
Text,
} from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI } from 'hooks';
import { useCommonHooks } from 'hooks';
import { useState } from 'react';
import { FiEdit, FiRefreshCcw, FiTrash } from 'react-icons/fi';
import { FiEdit, FiTrash } from 'react-icons/fi';
import type { Theme, ThemePlaylist } from 'types';
import DeleteItemModal from '../Shared/DeleteItemModal';
import ThemeMiniCard from './ThemeMiniCard';
@@ -24,14 +24,12 @@ function ThemePlaylistCard({
handleOpen: (cardPlaylist: ThemePlaylist) => void;
allThemes: Theme[];
}) {
const themePlaylistEndpoint = 'api/themePlaylists';
const [hover, setHover] = useState(false);
const { setThemeName, setCurrentThemePlaylist, theme, handleDelete } = useCommonHooks();
const syncableLists = ['All', 'Backgrounds', 'No Backgrounds'];
const { mutateAsync } = useMutationAPI();
const defaultLists = ['All', 'Backgrounds', 'No Backgrounds'];
const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false);
const themeList = JSON.parse(
cardPlaylist.themeList.name === 'Time of Day' ? '[]' : cardPlaylist.themeList,
cardPlaylist?.themeList?.name === 'Time of Day' ? '[]' : cardPlaylist.themeList,
);
return (
<Group
@@ -84,7 +82,7 @@ function ThemePlaylistCard({
>
{cardPlaylist.name}
</Text>
{syncableLists.includes(cardPlaylist.name) ? (
{!defaultLists.includes(cardPlaylist.name) && (
<ActionIcon
style={{
position: 'absolute',
@@ -100,104 +98,35 @@ function ThemePlaylistCard({
: 'var(--mantine-color-background-0)',
zIndex: 3,
}}
onClick={(event) => {
event.stopPropagation();
if (cardPlaylist.name === 'All') {
mutateAsync({
method: 'PATCH',
endpoint: themePlaylistEndpoint,
body: {
id: cardPlaylist.id,
name: 'All',
themeList: JSON.stringify(allThemes.map((theme: Theme) => theme.id)),
},
});
}
if (cardPlaylist.name === 'Backgrounds') {
mutateAsync({
method: 'PATCH',
endpoint: themePlaylistEndpoint,
body: {
id: cardPlaylist.id,
name: 'Backgrounds',
themeList: JSON.stringify(
allThemes
.filter(
(theme: Theme) => theme.backgroundImage.toLowerCase() !== 'none',
)
.map((theme: Theme) => theme.id),
),
},
});
}
if (cardPlaylist.name === 'No Backgrounds') {
mutateAsync({
method: 'PATCH',
endpoint: themePlaylistEndpoint,
body: {
id: cardPlaylist.id,
name: 'No Backgrounds',
themeList: JSON.stringify(
allThemes
.filter(
(theme: Theme) => theme.backgroundImage.toLowerCase() === 'none',
)
.map((theme: Theme) => theme.id),
),
},
});
}
onClick={() => {
handleOpen(cardPlaylist);
}}
>
<FiRefreshCcw />
<FiEdit />
</ActionIcon>
)}
{cardPlaylist.default === 0 && (
<ActionIcon
style={{
position: 'absolute',
top: -10,
right: 40,
paddingRight: 4,
paddingLeft: 4,
backgroundColor: 'var(--mantine-color-border-0)',
borderRadius: '4px',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
zIndex: 3,
}}
onClick={() => {
openModal();
}}
>
<FiTrash />
</ActionIcon>
) : (
<>
<ActionIcon
style={{
position: 'absolute',
top: -10,
right: 6,
paddingRight: 4,
paddingLeft: 4,
backgroundColor: 'var(--mantine-color-border-0)',
borderRadius: '4px',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
zIndex: 3,
}}
onClick={() => {
handleOpen(cardPlaylist);
}}
>
<FiEdit />
</ActionIcon>
{cardPlaylist.default === 0 && (
<ActionIcon
style={{
position: 'absolute',
top: -10,
right: 40,
paddingRight: 4,
paddingLeft: 4,
backgroundColor: 'var(--mantine-color-border-0)',
borderRadius: '4px',
color:
theme.borderColor === theme.primaryColor
? 'var(--mantine-color-accent-0)'
: 'var(--mantine-color-background-0)',
zIndex: 3,
}}
onClick={() => {
openModal();
}}
>
<FiTrash />
</ActionIcon>
)}
</>
)}
<Button
w={'275px'}

View File

@@ -4,7 +4,7 @@ import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import { FiChevronRight } from 'react-icons/fi';
import { textClasses } from 'styles';
import type { ThemePlaylist } from 'types';
import type { Theme, ThemePlaylist } from 'types';
import NoItemsFound from '../Shared/NoItemsFound';
import SettingsHeader from '../Shared/SettingsHeader';
import ThemePlaylistCard from './ThemePlaylistCard';
@@ -66,7 +66,6 @@ function ThemePlaylists() {
setIsLoading(false);
}
}, [themePlaylistData, isThemePlaylistDataFetched, debouncedSearch]);
return (
<Stack>
<ThemePlaylistModal
@@ -96,102 +95,207 @@ function ThemePlaylists() {
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
<Group mt={'6rem'} justify='center' align='center' pos={'relative'}>
<Text p={0} className={textClasses.settingsSubTitle} classNames={textClasses}>
Defaults
</Text>
</Group>
<Group justify='center' align='center' pos={'relative'}>
{themePlaylists.length > 0 ? (
themePlaylists
.filter((playlist: ThemePlaylist) => playlist.default === 1)
.map((cardPlaylist: ThemePlaylist) => {
return (
<Group key={cardPlaylist.name} pos={'relative'}>
{cardPlaylist.name === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2em',
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>
<ThemePlaylistCard
cardPlaylist={cardPlaylist}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
);
})
) : (
<Group w={'100%'} style={{ display: 'flex', justifyContent: 'center' }}>
<NoItemsFound />
{allThemeData ? (
<>
<Group mt={'6rem'} justify='center' align='center' pos={'relative'}>
<Text
p={0}
className={textClasses.settingsSubTitle}
classNames={textClasses}
>
Defaults
</Text>
</Group>
)}
</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 > 0 ? (
themePlaylists
.filter((playlist: ThemePlaylist) => playlist.default === 0)
.sort((a: ThemePlaylist, b: ThemePlaylist) => (a.name > b.name ? 1 : -1))
.map((cardPlaylist: ThemePlaylist) => {
return (
<Group key={cardPlaylist.name} pos={'relative'}>
{cardPlaylist.name === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2em',
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>
<ThemePlaylistCard
cardPlaylist={cardPlaylist}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
);
})
) : (
<Group w={'100%'} style={{ display: 'flex', justifyContent: 'center' }}>
<NoItemsFound />
<Group justify='center' align='center' pos={'relative'}>
<Group pos={'relative'}>
{'All' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2em',
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>
<ThemePlaylistCard
cardPlaylist={{
id: undefined,
name: 'All',
default: 1,
themeList: `[${allThemeData?.map((a: Theme) => a.id) ?? ''}]`,
}}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
<Group pos={'relative'}>
{'Backgrounds' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2em',
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>
<ThemePlaylistCard
cardPlaylist={{
id: undefined,
name: 'Backgrounds',
default: 1,
themeList: `[${allThemeData?.filter((a: any) => !a.backgroundImage.toLowerCase().includes('none')).map((a: Theme) => a.id) ?? ''}]`,
}}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
<Group pos={'relative'}>
{'No Backgrounds' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2em',
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>
<ThemePlaylistCard
cardPlaylist={{
id: undefined,
name: 'No Backgrounds',
default: 1,
themeList: `[${allThemeData?.filter((a: any) => a.backgroundImage.toLowerCase().includes('none')).map((a: Theme) => a.id) ?? ''}]`,
}}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
<Group pos={'relative'}>
{'Time of Day' === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2em',
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>
<ThemePlaylistCard
cardPlaylist={{
id: undefined,
name: 'Time of Day',
default: 1,
themeList:
themePlaylists?.filter(
(a: ThemePlaylist) => a.name === 'Time of Day',
)[0]?.themeList ?? '[]',
}}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
</Group>
)}
</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 > 0 ? (
themePlaylists
.filter((playlist: ThemePlaylist) => playlist.default === 0)
.sort((a: ThemePlaylist, b: ThemePlaylist) =>
a.name > b.name ? 1 : -1,
)
.map((cardPlaylist: ThemePlaylist) => {
return (
<Group key={cardPlaylist.name} pos={'relative'}>
{cardPlaylist.name === currentThemePlaylist && (
<FiChevronRight
style={{
position: 'absolute',
left: -14,
zIndex: 10,
fontSize: '2em',
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>
<ThemePlaylistCard
cardPlaylist={cardPlaylist}
handleOpen={handleOpen}
allThemes={allThemeData}
/>
</Box>
</Group>
);
})
) : (
<Group w={'100%'} style={{ display: 'flex', justifyContent: 'center' }}>
<NoItemsFound />
</Group>
)}
</Group>
</>
) : (
<></>
)}
</Stack>
</Stack>
);

View File

@@ -1,10 +1,11 @@
import { Box, Group, Overlay, Stack, Switch, Text } from '@mantine/core';
import { Box, Button, Group, Overlay, Stack, Switch, Text, Tooltip } from '@mantine/core';
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import { FaDice } from 'react-icons/fa';
import { FiChevronRight } from 'react-icons/fi';
import { switchClasses } from 'styles';
import { useNavigate } from 'react-router-dom';
import { switchClasses, textClasses } from 'styles';
import type { Theme, ThemePlaylist } from 'types';
import NoItemsFound from '../Shared/NoItemsFound';
import SettingsHeader from '../Shared/SettingsHeader';
@@ -45,8 +46,15 @@ function ThemesSettings() {
const [searchValue, setSearchValue] = useState('');
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
const [isLoading, setIsLoading] = useState(false);
const { currentTheme, setCurrentTheme, theme, isMobile, setCurrentThemePlaylist } =
useCommonHooks();
const navigate = useNavigate();
const {
currentTheme,
setCurrentTheme,
theme,
isMobile,
currentThemePlaylist,
setCurrentThemePlaylist,
} = useCommonHooks();
const handleOpen = (theme: Theme) => {
setSelectedTheme(theme);
@@ -102,7 +110,6 @@ function ThemesSettings() {
setIsLoading(false);
}
}, [allThemeData, isAllThemeDataFetched, debouncedSearch]);
return (
<Stack w={'100%'} align='center'>
<ThemeModal
@@ -136,36 +143,13 @@ function ThemesSettings() {
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
<Switch
label={
isMobile ? (
<FaDice size={20} color={'var(--mantine-color-primary-0)'} />
) : (
<Text c={'var(--mantine-color-primary-0)'}>Random Theme</Text>
)
}
labelPosition='left'
pos={'absolute'}
right={isMobile ? '2rem' : '1rem'}
top={isMobile ? '3.5rem' : '2rem'}
checked={currentTheme === 'random'}
onChange={(e) => {
setCurrentTheme(e.target.checked ? 'random' : theme.name);
setCurrentThemePlaylist('All');
}}
className={switchClasses.default}
classNames={switchClasses}
style={{
zIndex: 250,
}}
/>
<Group
w={'85%'}
justify='center'
align='center'
pos={'relative'}
mt={isMobile ? '10rem' : '7rem'}
mb={isMobile ? '6rem' : '1rem'}
mb={isMobile ? '8rem' : '6.5rem'}
>
<Overlay
display={currentTheme === 'random' && debouncedSearch === '' ? 'flex' : 'none'}
@@ -202,7 +186,16 @@ function ThemesSettings() {
<Box
style={{
zIndex:
currentTheme === 'random' && cardTheme.name === theme.name ? 195 : 0,
currentTheme === 'random' &&
(themePlaylists
.filter(
(t: ThemePlaylist) =>
t.name.toLowerCase() === currentThemePlaylist.toLowerCase(),
)[0]
?.themeList.includes(`${cardTheme.id}`) ||
cardTheme.name === theme.name)
? 195
: 0,
}}
>
<ThemeCard
@@ -223,6 +216,96 @@ function ThemesSettings() {
</Group>
)}
</Group>
<Group
align='center'
justify='center'
style={{
backdropFilter: 'blur(10px) brightness(.75)',
zIndex: 199,
paddingTop: '1.5rem',
paddingBottom: '1.5rem',
paddingLeft: '1rem',
paddingRight: '1rem',
height: 'min-content',
width: '100%',
marginTop: 0,
position: 'absolute',
bottom: 0,
}}
>
<Group w={isMobile ? undefined : '100%'}>
<Text
miw={isMobile ? 100 : undefined}
className={textClasses.settingsSubTitle}
classNames={textClasses}
>
Current Settings:
</Text>
<Group pos={isMobile ? undefined : 'absolute'} w={'100%'} justify='center'>
<Group align='center' justify='center'>
<Text
style={{
color: 'var(--mantine-color-accent-0)',
fontWeight: 'bold',
}}
>
Active Playlist:
</Text>
<Text
style={{
color: 'var(--mantine-color-primary-0)',
fontWeight: 'bold',
fontSize: '1.2em',
}}
>
{currentThemePlaylist === 'All' ? 'All' : currentThemePlaylist}
</Text>
</Group>
<Button
onClick={() => {
if (currentThemePlaylist === 'All') {
navigate(`/${import.meta.env.VITE_BASE_URL}/settings/themePlaylists`);
} else {
setCurrentThemePlaylist('All');
setCurrentTheme('random');
}
}}
>
{currentThemePlaylist === 'All' ? 'Select Playlist' : 'Disable Playlist'}
</Button>
<Tooltip
label='Shuffle is always on when a playlist is active.'
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
disabled={currentThemePlaylist === 'All'}
>
<Group>
<Switch
disabled={currentThemePlaylist !== 'All'}
label={
isMobile ? (
<FaDice size={20} color={'var(--mantine-color-primary-0)'} />
) : (
<Text c={'var(--mantine-color-primary-0)'}>Shuffle Enabled</Text>
)
}
labelPosition='left'
checked={currentTheme === 'random'}
onChange={(e) => {
setCurrentTheme(e.target.checked ? 'random' : theme.name);
setCurrentThemePlaylist('All');
}}
className={switchClasses.default}
classNames={switchClasses}
style={{
zIndex: 250,
}}
/>
</Group>
</Tooltip>
</Group>
</Group>
</Group>
</Stack>
);
}

View File

@@ -64,7 +64,8 @@ function DebouncedWolClient({
}
/>
<Tooltip
color={'var(--mantine-color-primary-0)'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
bd={'solid 1px var(--mantine-color-border-0)'}
label={'Delete'}
>

View File

@@ -22,11 +22,16 @@
&[data-active="true"] {
border-color: var(--mantine-color-primary-0);
}
width: 100%;
border-radius: 0%;
}
.tabLabel {
text-align: end;
}
.list {
border-top: solid 2px var(--mantine-color-accent-0);
padding-left: 2rem;
padding-top: 2rem;
padding-top: 1.75rem;
align-items: end;
}
.list::before {
border-color: var(--mantine-color-accent-0);