Standardization

This commit is contained in:
Sean Edmunds
2025-11-11 16:04:34 -06:00
parent 0397c0e1b0
commit 8794422a47
24 changed files with 365 additions and 209 deletions

View File

@@ -1,10 +1,5 @@
import { Box, Button, Group, Overlay, Stack, Text } from '@mantine/core';
import {
useDebouncedState,
useDisclosure,
useElementSize,
useHover,
} from '@mantine/hooks';
import { useDebouncedState, useDisclosure, useHover } from '@mantine/hooks';
import { DeleteItemModal } from 'components';
import { useCommonHooks } from 'hooks';
import { textClasses } from 'styles';
@@ -29,7 +24,6 @@ export function ThemeCard({
enabled?: boolean;
}) {
const { hovered, ref: hoverRef } = useHover();
const { ref, width } = useElementSize();
const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false);
const { currentTheme, setCurrentTheme, setCurrentThemePlaylist, handleDelete } =
useCommonHooks();
@@ -83,7 +77,7 @@ export function ThemeCard({
textOverflow: 'ellipsis',
overflow: 'hidden',
whiteSpace: 'nowrap',
maxWidth: width,
maxWidth: 275,
}}
>
{cardTheme.name}
@@ -111,19 +105,18 @@ export function ThemeCard({
/>
</Group>
<Button
ref={ref}
w={'275px'}
h={'115px'}
disabled={currentTheme === 'random'}
style={{
backgroundImage:
cardTheme?.backgroundImage.toLocaleLowerCase() !== 'none'
? `linear-gradient(${cardTheme?.backgroundColor}33, ${cardTheme?.backgroundColor}33), url(../../api/backgroundImages/thumbs/${cardTheme?.backgroundImage})`
: undefined,
cardTheme?.backgroundImage.toLocaleLowerCase() === 'none'
? undefined
: `linear-gradient(${cardTheme?.backgroundColor}33, ${cardTheme?.backgroundColor}33), url(../../api/backgroundImages/thumbs/${cardTheme?.backgroundImage})`,
backgroundSize:
cardTheme?.backgroundImage.toLocaleLowerCase() !== 'none'
? 'cover'
: undefined,
cardTheme?.backgroundImage.toLocaleLowerCase() === 'none'
? undefined
: 'cover',
backgroundColor:
cardTheme?.backgroundImage.toLocaleLowerCase() === 'none'
? cardTheme?.backgroundColor

View File

@@ -147,7 +147,7 @@ export function ThemeManagementPill({
position: 'absolute',
right: 3,
top: 3,
marginRight: !hovered ? 0 : '-2.5rem',
marginRight: hovered ? '-2.5rem' : 0,
transition: 'all 0.2s',
}}
align='center'

View File

@@ -13,11 +13,11 @@ export function ThemeMiniCard({ miniTheme }: { miniTheme: Theme | undefined }) {
h={'60px'}
style={{
backgroundImage:
miniTheme?.backgroundImage.toLocaleLowerCase() !== 'none'
? `linear-gradient(${miniTheme?.backgroundColor}33, ${miniTheme?.backgroundColor}33), url(../../api/backgroundImages/thumbs/${miniTheme?.backgroundImage})`
: undefined,
miniTheme?.backgroundImage.toLocaleLowerCase() === 'none'
? undefined
: `linear-gradient(${miniTheme?.backgroundColor}33, ${miniTheme?.backgroundColor}33), url(../../api/backgroundImages/thumbs/${miniTheme?.backgroundImage})`,
backgroundSize:
miniTheme?.backgroundImage.toLocaleLowerCase() !== 'none' ? 'cover' : undefined,
miniTheme?.backgroundImage.toLocaleLowerCase() === 'none' ? undefined : 'cover',
backgroundColor:
miniTheme?.backgroundImage.toLocaleLowerCase() === 'none'
? miniTheme?.backgroundColor

View File

@@ -37,7 +37,87 @@ export function NewThemeStarter({
}, []);
return (
<Stack align='center' p={'2rem'}>
{!duplicate ? (
{duplicate ? (
<Stack align='center'>
<Group
w={'100%'}
justify='center'
style={{
backgroundColor:
'color-mix(in srgb, var(--mantine-color-accent-0), var(--mantine-color-background-0))',
padding: '1rem',
borderRadius: '8px',
}}
>
{allThemes?.map((miniTheme: Theme) => {
return (
<Box
{...handlers}
key={miniTheme.id}
onClick={() => {
!pressed && setSelectedTheme(miniTheme);
setPressed(false);
}}
>
<ThemePreviewMiddleware
newThemeList={[miniTheme.id as number]}
miniTheme={miniTheme}
themeList={[]}
selectedPlaylist={undefined}
setSelectedPlaylist={() => {}}
/>
</Box>
);
})}
</Group>
<Group>
<Group
style={{
backgroundColor:
'color-mix(in srgb, var(--mantine-color-primary-0), var(--mantine-color-background-0))',
padding: '1rem',
borderRadius: '8px',
}}
>
<ThemeMiniCard miniTheme={selectedTheme} />
<Button
disabled={selectedTheme.name === 'default'}
onClick={() => {
setSelectedTheme({
...selectedTheme,
name: `${selectedTheme.name} copy`,
});
setIsNew(false);
}}
>
Confirm
</Button>
</Group>
<Button
color={'red'}
styles={{ label: { color: 'black' } }}
onClick={() => {
setDuplicate(false);
setSelectedTheme({
id: undefined,
name: 'Default',
backgroundImage: 'none',
backgroundColor: '#EEEEEE',
searchColor: '#00000033',
primaryColor: '#222222',
accentColor: '#5c5c5c',
borderColor: '#5c5c5c',
randomEnabled: 1,
textShadowsEnabled: 0,
appShadowsEnabled: 0,
});
}}
>
Back
</Button>
</Group>
</Stack>
) : (
<>
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
Please choose an option:
@@ -189,86 +269,6 @@ export function NewThemeStarter({
</Stack>
</Group>
</>
) : (
<Stack align='center'>
<Group
w={'100%'}
justify='center'
style={{
backgroundColor:
'color-mix(in srgb, var(--mantine-color-accent-0), var(--mantine-color-background-0))',
padding: '1rem',
borderRadius: '8px',
}}
>
{allThemes?.map((miniTheme: Theme) => {
return (
<Box
{...handlers}
key={miniTheme.id}
onClick={() => {
!pressed && setSelectedTheme(miniTheme);
setPressed(false);
}}
>
<ThemePreviewMiddleware
newThemeList={[miniTheme.id as number]}
miniTheme={miniTheme}
themeList={[]}
selectedPlaylist={undefined}
setSelectedPlaylist={() => {}}
/>
</Box>
);
})}
</Group>
<Group>
<Group
style={{
backgroundColor:
'color-mix(in srgb, var(--mantine-color-primary-0), var(--mantine-color-background-0))',
padding: '1rem',
borderRadius: '8px',
}}
>
<ThemeMiniCard miniTheme={selectedTheme} />
<Button
disabled={selectedTheme.name === 'default'}
onClick={() => {
setSelectedTheme({
...selectedTheme,
name: `${selectedTheme.name} copy`,
});
setIsNew(false);
}}
>
Confirm
</Button>
</Group>
<Button
color={'red'}
styles={{ label: { color: 'black' } }}
onClick={() => {
setDuplicate(false);
setSelectedTheme({
id: undefined,
name: 'Default',
backgroundImage: 'none',
backgroundColor: '#EEEEEE',
searchColor: '#00000033',
primaryColor: '#222222',
accentColor: '#5c5c5c',
borderColor: '#5c5c5c',
randomEnabled: 1,
textShadowsEnabled: 0,
appShadowsEnabled: 0,
});
}}
>
Back
</Button>
</Group>
</Stack>
)}
</Stack>
);

View File

@@ -84,7 +84,7 @@ export function ThemeEditor({
? `linear-gradient(${selectedTheme.backgroundColor}88, ${selectedTheme.backgroundColor}88), no-repeat center url(../../api/backgroundImages/thumbs/${item})`
: `no-repeat center url(../../api/backgroundImages/thumbs/${item})`
: 'repeating-linear-gradient(45deg, #33333366, #33333366 10px, #88888866 10px, #88888866 20px)',
backgroundSize: item !== 'none' ? 'cover' : undefined,
backgroundSize: item === 'none' ? undefined : 'cover',
backgroundColor: item === 'none' ? '#00000088' : undefined,
paddingLeft: '.5rem',
alignItems: 'center',
@@ -639,12 +639,12 @@ export function ThemeEditor({
</Tooltip>
<Button
onClick={() => {
!duplicate
? setSelectedTheme({ ...defaultTheme })
: setSelectedTheme({
duplicate
? setSelectedTheme({
...defaultTheme,
name: `${defaultTheme.name} copy`,
});
})
: setSelectedTheme({ ...defaultTheme });
}}
>
Reset Changes

View File

@@ -10,13 +10,13 @@ export function ThemeModalContent({ selectedTheme }: { selectedTheme: Theme }) {
<Stack
style={{
backgroundImage:
selectedTheme?.backgroundImage.toLocaleLowerCase() !== 'none'
? `linear-gradient(${selectedTheme?.backgroundColor}33, ${selectedTheme?.backgroundColor}33), url(../../api/backgroundImages/thumbs/${selectedTheme?.backgroundImage})`
: undefined,
selectedTheme?.backgroundImage.toLocaleLowerCase() === 'none'
? undefined
: `linear-gradient(${selectedTheme?.backgroundColor}33, ${selectedTheme?.backgroundColor}33), url(../../api/backgroundImages/thumbs/${selectedTheme?.backgroundImage})`,
backgroundSize:
selectedTheme?.backgroundImage.toLocaleLowerCase() !== 'none'
? 'cover'
: undefined,
selectedTheme?.backgroundImage.toLocaleLowerCase() === 'none'
? undefined
: 'cover',
backgroundColor:
selectedTheme?.backgroundImage.toLocaleLowerCase() === 'none'
? selectedTheme?.backgroundColor

View File

@@ -40,7 +40,9 @@ export function ThemePreviewMiddleware({
: undefined,
}}
onClick={() => {
if (!pressed) {
if (pressed) {
setPressed(false);
} else {
const newSelectedPlaylist = { ...selectedPlaylist };
if (themeList?.includes(miniTheme.id)) {
newThemeList.splice(themeList.indexOf(miniTheme.id), 1);
@@ -49,8 +51,6 @@ export function ThemePreviewMiddleware({
}
newSelectedPlaylist.themeList = JSON.stringify(newThemeList);
setSelectedPlaylist(newSelectedPlaylist);
} else {
setPressed(false);
}
}}
>

View File

@@ -3,6 +3,7 @@ import {
Button,
Divider,
Group,
LoadingOverlay,
Overlay,
Stack,
Switch,
@@ -24,11 +25,19 @@ import { ThemeModal } from './ThemeModal';
export function Themes() {
const backgroundsEndpoint = 'api/backgrounds';
const { data: allThemeData, isFetched: isAllThemeDataFetched } = useQueryAPI({
const {
data: allThemeData,
isFetched: allThemeDataIsFetched,
isFetching: allThemeDataIsFetching,
} = useQueryAPI({
endpoint: 'api/themes',
});
const [allThemes, setAllThemes] = useState<Theme[]>([]);
const { data: backgroundData, isFetched: isBackgroundFetched } = useQueryAPI({
const {
data: backgroundData,
isFetched: backgroundDataIsFetched,
isFetching: backgroundDataIsFetching,
} = useQueryAPI({
endpoint: backgroundsEndpoint,
});
const { data: themePlaylistData } = useQueryAPI({
@@ -76,13 +85,13 @@ export function Themes() {
};
useEffect(() => {
if (backgroundData && isBackgroundFetched) {
if (backgroundData && backgroundDataIsFetched) {
setBackgroundList([
'None',
...backgroundData.sort((a: string, b: string) => a.localeCompare(b)),
]);
}
}, [backgroundData, isBackgroundFetched]);
}, [backgroundData, backgroundDataIsFetched]);
useEffect(() => {
if (themePlaylistData) {
@@ -91,7 +100,7 @@ export function Themes() {
}, [themePlaylistData]);
useEffect(() => {
if (allThemeData && isAllThemeDataFetched) {
if (allThemeData && allThemeDataIsFetched) {
setAllThemes(
allThemeData.filter((a: Theme) =>
a.name.toLowerCase().includes(debouncedSearch.toLowerCase()),
@@ -101,7 +110,7 @@ export function Themes() {
if (debouncedSearch === searchValue) {
setIsLoading(false);
}
}, [allThemeData, isAllThemeDataFetched, debouncedSearch]);
}, [allThemeData, allThemeDataIsFetched, debouncedSearch]);
useEffect(() => {
if (allThemes) {
@@ -156,6 +165,16 @@ export function Themes() {
setIsLoading={setIsLoading}
/>
<Stack mt={isMobile ? '11rem' : '7rem'} align='center'>
<LoadingOverlay
visible={allThemeDataIsFetching || backgroundDataIsFetching}
zIndex={180}
overlayProps={{ blur: 5 }}
loaderProps={{
color: 'var(--mantine-color-primary-0)',
type: 'bars',
size: 'xl',
}}
/>
<Group
w={'85%'}
justify='center'
@@ -201,10 +220,10 @@ export function Themes() {
zIndex:
currentTheme === 'random' &&
(themePlaylists
.filter(
.find(
(t: ThemePlaylist) =>
t.name.toLowerCase() === currentThemePlaylist.toLowerCase(),
)[0]
)
?.themeList.includes(`${cardTheme.id}`) ||
cardTheme.name === theme.name)
? 195
@@ -222,10 +241,7 @@ export function Themes() {
</Group>
))
) : (
<Group
w={'100%'}
style={{ zIndex: 1000, display: 'flex', justifyContent: 'center' }}
>
<Group w={'100%'} style={{ display: 'flex', justifyContent: 'center' }}>
<NoItemsFound />
</Group>
)}