diff --git a/src/components/card/styled.tsx b/src/components/card/styled.tsx index 0f934a5..6da0068 100644 --- a/src/components/card/styled.tsx +++ b/src/components/card/styled.tsx @@ -19,12 +19,12 @@ interface Card { }; */ export const CardPanel = styled(Panel)` + border-radius: ${(props) => props.theme.other.card.borderRadius}; text-align: center; width: ${(props) => `${Number(props.cardsize) + 2}px`}; height: ${(props) => `${Number(props.cardsize) + 55}px`}; - border-radius: 0px !important; &:hover { - border: 1px solid ${(props) => props.theme.primary.main}; + border: 1px solid ${(props) => props.theme.colors.primary}; img { filter: brightness(70%); -webkit-filter: brightness(70%); @@ -41,7 +41,7 @@ export const InfoPanel = styled(Panel)` `; export const InfoSpan = styled.div` - color: ${(props) => props.theme.secondary.text}; + color: ${(props) => props.theme.colors.layout.page.colorSecondary}; `; export const CardButton = styled(Button)` @@ -53,14 +53,26 @@ export const CardButton = styled(Button)` export const CardTitleButton = styled(CardButton)` padding-top: 5px; padding-bottom: 2px; - color: ${(props) => props.theme.primary.text}; + color: ${(props) => props.theme.colors.layout.page.color}; width: ${(props) => `${props.cardsize}px`}; + + &:hover { + text-decoration: none; + color: ${(props) => + !props.onClick ? props.theme.colors.layout.page.color : props.theme.colors.primary}; + } `; export const CardSubtitleButton = styled(CardButton)` padding-bottom: 5px; - color: ${(props) => props.theme.secondary.text}; + color: ${(props) => props.theme.colors.layout.page.colorSecondary}; width: ${(props) => `${props.cardsize}px`}; + + &:hover { + text-decoration: none; + color: ${(props) => + !props.onClick ? props.theme.colors.layout.page.color : props.theme.colors.primary}; + } `; export const CardSubtitle = styled.div` @@ -83,7 +95,6 @@ export const LazyCardImg = styled(LazyLoadImage)` `; export const Overlay = styled.div` - background-color: #1a1d24; position: relative; height: ${(props) => `${props.cardsize}px`}; width: ${(props) => `${props.cardsize}px`}; @@ -93,7 +104,7 @@ export const Overlay = styled.div` .corner-triangle { position: absolute; - background-color: ${(props) => props.theme.primary.main}; + background-color: ${(props) => props.theme.colors.primary}; box-shadow: 0 0 10px 8px rgba(0, 0, 0, 0.8); height: 80px; left: -50px; @@ -108,16 +119,18 @@ export const Overlay = styled.div` const OverlayButton = styled(IconButton)` display: none; position: absolute !important; - opacity: 0.8; + opacity: ${(props) => props.theme.colors.card.overlayButton.opacity}; width: 0px; height: 0px; transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); - background: #000; + background: ${(props) => props.theme.colors.card.overlayButton.background}; + color: ${(props) => props.theme.colors.card.overlayButton.color}; &:hover { opacity: 1; - background: ${(props) => props.theme.primary.main}; + background: ${(props) => props.theme.colors.card.overlayButton.backgroundHover}; + color: ${(props) => props.theme.colors.card.overlayButton.colorHover}; } `; diff --git a/src/components/layout/GenericPageHeader.tsx b/src/components/layout/GenericPageHeader.tsx index a53ed52..1526fb1 100644 --- a/src/components/layout/GenericPageHeader.tsx +++ b/src/components/layout/GenericPageHeader.tsx @@ -2,9 +2,14 @@ import React, { useState } from 'react'; import { LazyLoadImage } from 'react-lazy-load-image-component'; import { useHistory } from 'react-router-dom'; import { useHotkeys } from 'react-hotkeys-hook'; -import { Icon, Input, InputGroup } from 'rsuite'; +import { Icon, InputGroup } from 'rsuite'; import ViewTypeButtons from '../viewtypes/ViewTypeButtons'; -import { StyledIconButton, StyledInputGroup } from '../shared/styled'; +import { + StyledIconButton, + StyledInput, + StyledInputGroup, + StyledInputGroupButton, +} from '../shared/styled'; import { CoverArtWrapper, PageHeaderTitle } from './styled'; import cacheImage from '../shared/cacheImage'; import CustomTooltip from '../shared/CustomTooltip'; @@ -98,7 +103,7 @@ const GenericPageHeader = ({ - - { clearSearchQuery(); @@ -123,7 +128,7 @@ const GenericPageHeader = ({ }} > - + ) : ( diff --git a/src/components/layout/styled.tsx b/src/components/layout/styled.tsx index be31527..ef8218f 100644 --- a/src/components/layout/styled.tsx +++ b/src/components/layout/styled.tsx @@ -1,13 +1,13 @@ import React from 'react'; import styled from 'styled-components'; -import { Container, Content, Footer, Header, Sidebar } from 'rsuite'; +import { Container, Content, Footer, Header, Nav, Sidebar } from 'rsuite'; // Layout.tsx export const RootContainer = styled(Container)<{ font: string }>` - background: ${(props) => props.theme.primary.background}; + background: ${(props) => props.theme.colors.layout.page.background}; height: 100vh; - color: ${(props) => props.theme.primary.text}; - font-size: ${(props) => props.theme.all.fonts.pageFontSize}; + color: ${(props) => props.theme.colors.layout.page.color}; + font-size: ${(props) => `${props.theme.fonts.size.page} !important`}; font-family: ${(props) => `${props.font?.split(/Light|Medium/)[0]}`}; font-weight: ${(props) => props.font?.match('Light') ? 300 : props.font?.match('Medium') ? 500 : 400}; @@ -42,9 +42,9 @@ export const TitleHeader = styled.header<{ font: string }>` position: fixed; height: 32px; width: ${(props) => (props.className?.includes('maximized') ? '100%' : 'calc(100%)')}; - background: ${(props) => props.theme.primary.titleBar}; + background: ${(props) => props.theme.colors.layout.titleBar.background}; padding: 4px; - color: ${(props) => props.theme.primary.titleText}; + color: ${(props) => props.theme.colors.layout.titleBar.color}; font-family: ${(props) => `${props.font?.split(/Light|Medium/)[0]}`}; font-weight: ${(props) => props.font?.match('Light') ? 300 : props.font?.match('Medium') ? 500 : 400}; @@ -161,7 +161,7 @@ export const PageContent = styled(Content)<{ padding?: string }>` // Sidebar.tsx // Add 1 to top if you add window border export const FixedSidebar = styled(Sidebar)<{ font: string }>` - background: ${(props) => props.theme.primary.sideBar} !important; + background: ${(props) => props.theme.colors.layout.sideBar.background} !important; position: fixed; top: 32px; z-index: 1; @@ -177,14 +177,24 @@ export const FixedSidebar = styled(Sidebar)<{ font: string }>` } `; +export const SidebarNavItem = styled(Nav.Item)` + a { + color: ${(props) => props.theme.colors.layout.sideBar.button.color} !important; + + &:hover { + color: ${(props) => props.theme.colors.layout.sideBar.button.colorHover} !important; + } + } +`; + export const CoverArtWrapper = styled.div` display: inline-block; - filter: ${(props) => `drop-shadow(0px 5px 8px ${props.theme.primary.coverArtShadow})`}; + filter: ${(props) => props.theme.other.coverArtFilter}; `; export const PageHeaderTitle = styled.h1` text-overflow: ellipsis; white-space: nowrap; overflow: hidden; - font-size: ${(props) => props.theme.all.fonts.pageTitleFontSize}; + font-size: ${(props) => props.theme.fonts.size.pageTitle}; `; diff --git a/src/components/library/ArtistView.tsx b/src/components/library/ArtistView.tsx index f080531..6520136 100644 --- a/src/components/library/ArtistView.tsx +++ b/src/components/library/ArtistView.tsx @@ -3,7 +3,7 @@ import React, { useState } from 'react'; import _ from 'lodash'; import { shell } from 'electron'; import settings from 'electron-settings'; -import { ButtonToolbar, Tag, Whisper, Button, Popover, TagGroup } from 'rsuite'; +import { ButtonToolbar, Whisper, TagGroup } from 'rsuite'; import { useQuery, useQueryClient } from 'react-query'; import { useParams, useHistory } from 'react-router-dom'; import { @@ -32,7 +32,7 @@ import { addModalPage } from '../../redux/miscSlice'; import { appendPlayQueue, setPlayQueue } from '../../redux/playQueueSlice'; import { notifyToast } from '../shared/toast'; import { isCached } from '../../shared/utils'; -import { StyledButton } from '../shared/styled'; +import { StyledButton, StyledPopover, StyledTag } from '../shared/styled'; import { setStatus } from '../../redux/playerSlice'; interface ArtistParams { @@ -213,12 +213,12 @@ const ArtistView = ({ ...rest }: any) => { trigger="hover" enterable speaker={ - +
Related artists
{artistInfo.similarArtist?.map((artist: any) => ( - + { if (!rest.isModal) { @@ -235,7 +235,7 @@ const ArtistView = ({ ...rest }: any) => { > {artist.name} - + ))}
@@ -247,10 +247,10 @@ const ArtistView = ({ ...rest }: any) => { > View on Last.FM -
+ } > - + Info diff --git a/src/components/loader/PageLoader.tsx b/src/components/loader/PageLoader.tsx index 4e3d824..99f1ed3 100644 --- a/src/components/loader/PageLoader.tsx +++ b/src/components/loader/PageLoader.tsx @@ -10,10 +10,11 @@ const LoaderContainer = styled.div` div { span { &:after { - border-color: ${(props) => `${props.theme.primary.main} transparent transparent`}; + border-color: ${(props) => + `${props.theme.colors.spinner.foreground} transparent transparent`}; } &:before { - border: ${(props) => `3px solid ${props.theme.primary.spinnerBackground}`}; + border: ${(props) => `3px solid ${props.theme.colors.spinner.background}`}; } } } diff --git a/src/components/modal/PageModal.tsx b/src/components/modal/PageModal.tsx index 4ceb146..ae4fbc7 100644 --- a/src/components/modal/PageModal.tsx +++ b/src/components/modal/PageModal.tsx @@ -9,14 +9,14 @@ import AlbumView from '../library/AlbumView'; import PlaylistView from '../playlist/PlaylistView'; const StyledModal = styled(Modal)` - color: ${(props) => `${props.theme.primary.text} !important`}; + color: ${(props) => `${props.theme.colors.layout.page.color} !important`}; .rs-modal-body { margin-top: 0px; } .rs-modal-content { - background: ${(props) => `${props.theme.primary.background} !important`}; + background: ${(props) => `${props.theme.colors.layout.page.background} !important`}; } .rs-container { diff --git a/src/components/player/NowPlayingView.tsx b/src/components/player/NowPlayingView.tsx index cdae991..f2f7382 100644 --- a/src/components/player/NowPlayingView.tsx +++ b/src/components/player/NowPlayingView.tsx @@ -37,9 +37,9 @@ import { AutoPlaylistButton, ClearQueueButton, ShuffleButton } from '../shared/T import { StyledButton, StyledCheckbox, - StyledInputGroup, StyledInputNumber, StyledInputPicker, + StyledInputPickerContainer, StyledPopover, } from '../shared/styled'; import { errorMessages, getCurrentEntryList, isFailedResponse } from '../../shared/utils'; @@ -48,6 +48,7 @@ import { notifyToast } from '../shared/toast'; const NowPlayingView = () => { const tableRef = useRef(); + const pickerContainerRef = useRef(null); const autoPlaylistTriggerRef = useRef(); const dispatch = useAppDispatch(); const playQueue = useAppSelector((state) => state.playQueue); @@ -268,71 +269,66 @@ const NowPlayingView = () => { speaker={ How many tracks? (1-500)* - - { - settings.setSync('randomPlaylistTrackCount', Number(e)); - setRandomPlaylistTrackCount(Number(e)); - }} - /> - - + { + settings.setSync('randomPlaylistTrackCount', Number(e)); + setRandomPlaylistTrackCount(Number(e)); + }} + />
- From year
- - { - setRandomPlaylistFromYear(Number(e)); - }} - /> - + { + setRandomPlaylistFromYear(Number(e)); + }} + />
To year
- - setRandomPlaylistToYear(Number(e))} - /> - + setRandomPlaylistToYear(Number(e))} + />

Genre -
+ pickerContainerRef.current} data={genres} value={randomPlaylistGenre} virtualized onChange={(e: string) => setRandomPlaylistGenre(e)} /> -
+
handlePlayRandom('addNext')} loading={isLoadingRandom} disabled={!(typeof autoPlaylistTrackCount === 'number')} @@ -340,6 +336,7 @@ const NowPlayingView = () => { Add (next) handlePlayRandom('addLater')} loading={isLoadingRandom} disabled={!(typeof autoPlaylistTrackCount === 'number')} diff --git a/src/components/player/PlayerBar.tsx b/src/components/player/PlayerBar.tsx index a70132e..baf5cf2 100644 --- a/src/components/player/PlayerBar.tsx +++ b/src/components/player/PlayerBar.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState, useRef } from 'react'; import { useQueryClient } from 'react-query'; import settings from 'electron-settings'; -import { FlexboxGrid, Grid, Row, Col, Whisper, Popover } from 'rsuite'; +import { FlexboxGrid, Grid, Row, Col, Whisper } from 'rsuite'; import { useHistory } from 'react-router-dom'; import { LazyLoadImage } from 'react-lazy-load-image-component'; import format from 'format-duration'; @@ -34,6 +34,7 @@ import placeholderImg from '../../img/placeholder.jpg'; import DebugWindow from '../debug/DebugWindow'; import { CoverArtWrapper } from '../layout/styled'; import { getCurrentEntryList, isCached } from '../../shared/utils'; +import { StyledPopover } from '../shared/styled'; const PlayerBar = () => { const queryClient = useQueryClient(); @@ -321,7 +322,7 @@ const PlayerBar = () => { placement="topStart" preventOverflow speaker={ - +
{ height={500} />
-
+
} > props.theme.primary.playerBar}; + background: ${(props) => props.theme.colors.layout.playerBar.background}; height: 100%; - border-top: 1px solid #48545c; + border-top: ${(props) => props.theme.other.playerBar.borderTop}; + border-right: ${(props) => props.theme.other.playerBar.borderRight}; + border-bottom: ${(props) => props.theme.other.playerBar.borderBottom}; + border-left: ${(props) => props.theme.other.playerBar.borderLeft}; + filter: ${(props) => props.theme.other.playerBar.filter}; `; export const PlayerColumn = styled.div<{ @@ -23,14 +27,16 @@ export const PlayerColumn = styled.div<{ export const PlayerControlIcon = styled(Icon)` font-size: medium; color: ${(props) => - props.active === 'true' ? props.theme.primary.main : props.theme.primary.playerBarButtons}; + props.active === 'true' + ? props.theme.colors.primary + : props.theme.colors.layout.playerBar.button.color}; padding-left: 10px; padding-right: 10px; &:hover { color: ${(props) => props.active === 'true' - ? props.theme.primary.main - : props.theme.primary.playerBarButtonsHover}; + ? props.theme.colors.primary + : props.theme.colors.layout.playerBar.button.colorHover}; } cursor: pointer; `; @@ -43,23 +49,23 @@ export const LinkButton = styled.a<{ subtitle?: string }>` overflow: hidden; color: ${(props) => props.subtitle === 'true' - ? props.theme.secondary.playerBarText - : props.theme.primary.playerBarText}; + ? props.theme.colors.layout.playerBar.colorSecondary + : props.theme.colors.layout.playerBar.color}; &:hover { text-decoration: underline; color: ${(props) => props.subtitle === 'true' - ? props.theme.secondary.playerBarText - : props.theme.primary.playerBarText}; + ? props.theme.colors.layout.playerBar.colorSecondary + : props.theme.colors.layout.playerBar.color}; cursor: pointer; } &:active { color: ${(props) => props.subtitle === 'true' - ? props.theme.secondary.playerBarText - : props.theme.primary.playerBarText}; + ? props.theme.colors.layout.playerBar.colorSecondary + : props.theme.colors.layout.playerBar.color}; } `; @@ -69,26 +75,31 @@ export const CustomSlider = styled(Slider)<{ isDragging?: boolean }>` display: block; } .rs-slider-progress-bar { - background-color: ${(props) => props.theme.primary.main}; + background-color: ${(props) => props.theme.colors.primary}; } } + + .rs-slider-bar { + background-color: ${(props) => props.theme.colors.slider.background}; + } + .rs-slider-progress-bar { background-color: ${(props) => - props.$isDragging ? props.theme.primary.main : props.theme.primary.sliderBackground}; + props.$isDragging ? props.theme.colors.primary : props.theme.colors.slider.progressBar}; } .rs-slider-handle::before { display: none; - border: ${(props) => `1px solid ${props.theme.primary.main} !important`}; + border: ${(props) => `1px solid ${props.theme.colors.primary} !important`}; } `; export const DurationSpan = styled.span` - color: ${(props) => props.theme.primary.playerBarText}; + color: ${(props) => props.theme.colors.layout.playerBar.color}; `; export const VolumeIcon = styled(Icon)` - color: ${(props) => props.theme.primary.playerBarText}; + color: ${(props) => props.theme.colors.layout.playerBar.color}; `; export const MiniViewContainer = styled.div<{ display: string }>` @@ -99,12 +110,12 @@ export const MiniViewContainer = styled.div<{ display: string }>` right: 25px; padding: 8px; width: 400px; - height: 450px; - background: ${(props) => props.theme.primary.background}; + height: ${(props) => props.theme.other.miniPlayer.height}; + background: ${(props) => props.theme.colors.layout.page.background}; border: 1px #000 solid; filter: drop-shadow(0px 1px 2px #121316); overflow: hidden auto; - opacity: ${(props) => (props.display === 'true' ? 0.95 : 0)}; - color: ${(props) => `${props.theme.primary.text} !important`}; + opacity: ${(props) => (props.display === 'true' ? props.theme.other.miniPlayer.opacity : 0)}; + color: ${(props) => `${props.theme.colors.layout.page.color} !important`}; z-index: 500; `; diff --git a/src/components/playlist/PlaylistList.tsx b/src/components/playlist/PlaylistList.tsx index 7b66008..84df485 100644 --- a/src/components/playlist/PlaylistList.tsx +++ b/src/components/playlist/PlaylistList.tsx @@ -1,7 +1,7 @@ import React, { useRef, useState } from 'react'; import { useQuery, useQueryClient } from 'react-query'; import { useHistory } from 'react-router-dom'; -import { Form, Input, Popover, Whisper } from 'rsuite'; +import { Form, Input, Whisper } from 'rsuite'; import settings from 'electron-settings'; import useSearchQuery from '../../hooks/useSearchQuery'; import { createPlaylist, getPlaylists } from '../../api/api'; @@ -10,7 +10,7 @@ import PageLoader from '../loader/PageLoader'; import GenericPage from '../layout/GenericPage'; import GenericPageHeader from '../layout/GenericPageHeader'; import GridViewType from '../viewtypes/GridViewType'; -import { StyledButton, StyledInputGroup } from '../shared/styled'; +import { StyledButton, StyledInputGroup, StyledPopover } from '../shared/styled'; import { errorMessages, isFailedResponse } from '../../shared/utils'; import { notifyToast } from '../shared/toast'; import { AddPlaylistButton } from '../shared/ToolbarButtons'; @@ -99,7 +99,7 @@ const PlaylistList = () => { placement="auto" trigger="click" speaker={ - +
{ Create -
+ } > { placement="auto" trigger="click" speaker={ - +
{ Edit -
+ } > @@ -461,12 +461,12 @@ const PlaylistView = ({ ...rest }) => { placement="auto" trigger="click" speaker={ - +

Are you sure you want to delete this playlist?

Yes -
+ } > { - console.log(e); if (e.key === ' ' || e.key === 'Enter') { onClickTitle(); } @@ -51,24 +50,28 @@ const ScrollingMenu = ({ - - - } - onClick={() => { - scrollContainerRef.current.scrollLeft -= - config.lookAndFeel.gridView.cardSize * 5; - }} - /> - } - onClick={() => { - scrollContainerRef.current.scrollLeft += - config.lookAndFeel.gridView.cardSize * 5; - }} - /> - - + {data.length > 0 && ( + + + } + onClick={() => { + scrollContainerRef.current.scrollLeft -= + config.lookAndFeel.gridView.cardSize * 5; + }} + /> + } + onClick={() => { + scrollContainerRef.current.scrollLeft += + config.lookAndFeel.gridView.cardSize * 5; + }} + /> + + + )} diff --git a/src/components/settings/Config.tsx b/src/components/settings/Config.tsx index fab08ad..56cc59b 100644 --- a/src/components/settings/Config.tsx +++ b/src/components/settings/Config.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from 'react'; import axios from 'axios'; import { shell } from 'electron'; -import { Button, Whisper, Popover, Nav, ButtonToolbar } from 'rsuite'; +import { Whisper, Nav, ButtonToolbar } from 'rsuite'; import { startScan, getScanStatus } from '../../api/api'; import GenericPage from '../layout/GenericPage'; import DisconnectButton from './DisconnectButton'; import GenericPageHeader from '../layout/GenericPageHeader'; import setDefaultSettings from '../shared/setDefaultSettings'; -import { StyledButton, StyledNavItem } from '../shared/styled'; +import { StyledButton, StyledNavItem, StyledPopover } from '../shared/styled'; import PlaybackConfig from './ConfigPanels/PlaybackConfig'; import LookAndFeelConfig from './ConfigPanels/LookAndFeelConfig'; import PlayerConfig from './ConfigPanels/PlayerConfig'; @@ -106,23 +106,23 @@ const Config = () => { trigger="click" placement="auto" speaker={ - +
Are you sure you want to reset your settings to default?
+ WARNING: This will reload the application
- - WARNING: This will reload the application +
-
+ } > Reset defaults @@ -133,7 +133,7 @@ const Config = () => { enterable preventOverflow speaker={ - + <> Current version: {packageJson.version}
@@ -165,7 +165,7 @@ const Config = () => { View CHANGELOG -
+ } > { <> setNewCachePath(e)} /> - { const check = fs.existsSync(newCachePath); if (check) { @@ -131,16 +140,16 @@ const CacheConfig = () => { }} > - - + { setIsEditingCachePath(false); setErrorMessage(''); }} > - - + { const defaultPath = path.join(path.dirname(settings.file())); settings.setSync('cachePath', defaultPath); @@ -151,7 +160,7 @@ const CacheConfig = () => { }} > Reset to default - +

*You will need to manually move any existing cached files to their new location. @@ -163,7 +172,7 @@ const CacheConfig = () => { Location:{' '}

shell.openPath(getRootCachePath())}> - {getRootCachePath()} + {getRootCachePath()}
@@ -177,9 +186,9 @@ const CacheConfig = () => { }} > Songs{' '} - + {songCacheSize} MB {imgCacheSize === 9999999 && '- Folder not found'} - + { }} > Images{' '} - + {imgCacheSize} MB {imgCacheSize === 9999999 && '- Folder not found'} - +
- + setIsEditingCachePath(true)}>Edit cache location + Which cache would you like to clear? - - - - - +
- + } > - + Clear cache diff --git a/src/components/settings/ConfigPanels/ListViewConfig.tsx b/src/components/settings/ConfigPanels/ListViewConfig.tsx index 97c4fa4..7a1e505 100644 --- a/src/components/settings/ConfigPanels/ListViewConfig.tsx +++ b/src/components/settings/ConfigPanels/ListViewConfig.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useState } from 'react'; import { nanoid } from 'nanoid/non-secure'; import settings from 'electron-settings'; -import { TagPicker, ControlLabel } from 'rsuite'; -import { StyledInputNumber, StyledPanel } from '../../shared/styled'; +import { ControlLabel } from 'rsuite'; +import { StyledInputNumber, StyledPanel, StyledTagPicker } from '../../shared/styled'; import ListViewTable from '../../viewtypes/ListViewTable'; import { useAppDispatch, useAppSelector } from '../../../redux/hooks'; import { @@ -100,12 +100,12 @@ const ListViewConfig = ({ defaultColumns, columnPicker, columnList, settingsConf
- { + onChange={(e: any) => { const columns: any[] = []; if (e) { e.forEach((selected: string) => { diff --git a/src/components/settings/DisconnectButton.tsx b/src/components/settings/DisconnectButton.tsx index b5c7166..f984ae4 100644 --- a/src/components/settings/DisconnectButton.tsx +++ b/src/components/settings/DisconnectButton.tsx @@ -1,6 +1,6 @@ import React from 'react'; import settings from 'electron-settings'; -import { Button } from 'rsuite'; +import { StyledButton } from '../shared/styled'; const DisconnectButton = () => { const handleDisconnect = () => { @@ -17,9 +17,9 @@ const DisconnectButton = () => { window.location.reload(); }; return ( - + ); }; diff --git a/src/components/settings/styled.tsx b/src/components/settings/styled.tsx index efe30c8..aca2c47 100644 --- a/src/components/settings/styled.tsx +++ b/src/components/settings/styled.tsx @@ -2,27 +2,27 @@ import styled from 'styled-components'; import { Panel } from 'rsuite'; export const ConfigPanel = styled(Panel)` - color: ${(props) => props.theme.primary.text}; + color: ${(props) => props.theme.colors.layout.page.color}; padding: 20px; min-width: 500px; max-width: 800px; margin: 15px auto 15px auto; - border-radius: 0px; + border-radius: ${(props) => props.theme.other.panel.borderRadius}; .rs-panel-heading { - font-size: ${(props) => props.theme.all.fonts.panelHeaderFontSize}; + font-size: ${(props) => props.theme.fonts.size.panelTitle}; } `; export const MockFooter = styled.div` width: 100%; height: 100%; - background: ${(props) => props.theme.primary.playerBar}; + background: ${(props) => props.theme.colors.layout.playerBar.background}; border-top: 1px solid #48545c; `; export const LoginPanel = styled(Panel)` - color: ${(props) => props.theme.primary.text}; + color: ${(props) => props.theme.colors.layout.page.color}; padding: 20px; min-width: 300px; max-width: 300px; diff --git a/src/components/shared/ContextMenu.tsx b/src/components/shared/ContextMenu.tsx index 7ead5be..e19a1f4 100644 --- a/src/components/shared/ContextMenu.tsx +++ b/src/components/shared/ContextMenu.tsx @@ -4,7 +4,7 @@ import _ from 'lodash'; import { nanoid } from 'nanoid/non-secure'; import { useQuery, useQueryClient } from 'react-query'; import { useHistory } from 'react-router'; -import { Col, FlexboxGrid, Form, Grid, Icon, Input, Row, Whisper } from 'rsuite'; +import { Col, FlexboxGrid, Form, Grid, Icon, Row, Whisper } from 'rsuite'; import { getPlaylists, updatePlaylistSongsLg, @@ -51,9 +51,10 @@ import { StyledInputPicker, StyledButton, StyledInputGroup, - StyledPopover, StyledInputNumber, - StyledIconButton, + StyledInputPickerContainer, + ContextMenuPopover, + StyledInput, } from './styled'; import { notifyToast } from './toast'; import { errorMessages, getCurrentEntryList, isFailedResponse } from '../../shared/utils'; @@ -555,8 +556,38 @@ export const GlobalContextMenu = () => { enterable placement="autoHorizontalStart" trigger="hover" + delayShow={300} speaker={ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
{
- - - - - } - onClick={handleMoveToTop} - block - > - Top - - - - } - onClick={handleMoveUpOne} - block - > - Up - - - - - - } - onClick={handleMoveToBottom} - block - > - Bottom - - - - - } - onClick={handleMoveDownOne} - block - > - Down - - - - -
+ } > { placement="autoHorizontalStart" trigger="none" speaker={ - - - setSelectedPlaylistId(e)} - /> - - Add - - + + + + playlistPickerContainerRef.current} + data={playlists} + placement="autoVerticalStart" + virtualized + labelKey="name" + valueKey="id" + width={200} + onChange={(e: any) => setSelectedPlaylistId(e)} + /> + + Add + + +
{ {shouldCreatePlaylist && (
- - setNewPlaylistName(e)} - /> - -
+ setNewPlaylistName(e)} + /> { )} - + } > { placement="autoHorizontalStart" trigger="none" speaker={ - +

Are you sure you want to delete {multiSelect.selected?.length} playlist(s)?

Yes -
+ } > props.theme.primary.background}; - color: ${(props) => props.theme.primary.text}; + background-color: ${(props) => props.theme.colors.tooltip.background}; + color: ${(props) => props.theme.colors.tooltip.color}; + border-radius: ${(props) => props.theme.other.tooltip.borderRadius}; + border: ${(props) => props.theme.other.tooltip.border}; } `; diff --git a/src/components/shared/ToolbarButtons.tsx b/src/components/shared/ToolbarButtons.tsx index da68ba5..ad59ecc 100644 --- a/src/components/shared/ToolbarButtons.tsx +++ b/src/components/shared/ToolbarButtons.tsx @@ -98,7 +98,9 @@ export const DownloadButton = ({ ...rest }) => { export const ShuffleButton = ({ ...rest }) => { return ( - } tabIndex={0} {...rest} /> + + + ); }; @@ -106,7 +108,9 @@ export const ShuffleButton = ({ ...rest }) => { export const ClearQueueButton = ({ ...rest }) => { return ( - } tabIndex={0} {...rest} /> + + + ); }; diff --git a/src/components/shared/setDefaultSettings.ts b/src/components/shared/setDefaultSettings.ts index f9c97ff..490800b 100644 --- a/src/components/shared/setDefaultSettings.ts +++ b/src/components/shared/setDefaultSettings.ts @@ -425,6 +425,295 @@ const setDefaultSettings = (force: boolean) => { }, ]); } + + if (force || !settings.hasSync('themes')) { + settings.setSync('themes', [ + { + label: 'Default Dark', + value: 'defaultDark', + fonts: { + size: { + page: '14px', + pageTitle: '40px', + panelTitle: '20px', + }, + }, + colors: { + primary: '#2196F3', + layout: { + page: { + color: '#D8D8D8', + colorSecondary: '#888e94', + background: '#181A1F', + }, + playerBar: { + color: '#D8D8D8', + colorSecondary: '#888e94', + background: '#101010', + button: { + color: 'rgba(240, 240, 240, 0.8)', + colorHover: '#FFFFFF', + }, + }, + sideBar: { + background: '#101010', + button: { + color: '#D8D8D8', + colorHover: '#FFFFFF', + }, + }, + titleBar: { + color: '#FFFFFF', + background: '#101010', + }, + }, + button: { + default: { + color: '#D8D8D8', + colorHover: '#FFFFFF', + background: '#292D33', + backgroundHover: '#3C3F43', + }, + primary: { + color: '#FFFFFF', + colorHover: '#FFFFFF', + backgroundHover: '#3B89EC', + }, + subtle: { + color: '#D8D8D8', + colorHover: '#D8D8D8', + backgroundHover: 'transparent', + }, + link: { + color: '#2196F3', + colorHover: '#3B89EC', + }, + }, + card: { + overlayButton: { + color: '#FFFFFF', + background: '#000000', + opacity: 0.8, + }, + }, + contextMenu: { + color: '#D8D8D8', + colorDisabled: '#6A6F76', + background: '#1E2125', + backgroundHover: '#292D33', + }, + input: { + color: '#D8D8D8', + background: '#25292E', + backgroundHover: '#353A45', + backgroundActive: 'rgba(240, 240, 240, .2)', + }, + nav: { + color: '#D8D8D8', + }, + popover: { + color: '#D8D8D8', + background: '#1E2125', + }, + slider: { + background: '#3C3F43', + progressBar: '#888E94', + }, + spinner: { + background: 'rgba(233, 235, 240, 0.3)', + foreground: '#2196F3', + }, + table: { + selectedRow: '#4D5156', + }, + tag: { + background: '#3C3F43', + text: '#E2E4E9', + }, + tooltip: { + color: '#D8D8D8', + background: '#1E2125', + }, + }, + other: { + button: { + borderRadius: '0px', + }, + coverArtFilter: 'drop-shadow(0px 3px 5px #000000)', + card: { + borderRadius: '0px', + }, + input: { + borderRadius: '0px', + }, + miniPlayer: { + height: '450px', + opacity: 0.95, + }, + panel: { + borderRadius: '0px', + }, + playerBar: { + borderTop: '1px solid rgba(240, 240, 240, .15)', + borderRight: 'none', + borderBottom: 'none', + borderLeft: 'none', + filter: 'none', + }, + tag: { + borderRadius: '0px', + }, + tooltip: { + border: '1px #3c3f43 solid', + borderRadius: '0px', + }, + }, + }, + { + label: 'Default Light', + value: 'defaultLight', + fonts: { + size: { + page: '14px', + pageTitle: '30px', + panelTitle: '20px', + }, + }, + colors: { + primary: '#285DA0', + layout: { + page: { + color: '#000000', + colorSecondary: '#888e94', + background: '#FFFFFF', + }, + playerBar: { + color: '#FFFFFF', + colorSecondary: '#888e94', + background: '#161B22', + button: { + color: 'rgba(240, 240, 240, 0.8)', + colorHover: '#FFFFFF', + }, + }, + sideBar: { + background: '#161B22', + button: { + color: '#D8D8D8', + colorHover: '#FFFFFF', + }, + }, + titleBar: { + color: '#FFFFFF', + background: '#161B22', + }, + }, + button: { + default: { + color: '#575757', + colorHover: '#000000', + background: '#DFDFE2', + backgroundHover: '#D2D2D6', + }, + primary: { + color: '#FFFFFF', + colorHover: '#FFFFFF', + backgroundHover: '#347AD3', + }, + subtle: { + color: '#575757', + colorHover: '#575757', + backgroundHover: 'transparent', + }, + link: { + color: '#575757', + colorHover: '#575757', + }, + }, + card: { + overlayButton: { + color: '#FFFFFF', + colorHover: '#FFFFFF', + background: '#000000', + backgroundHover: '#285DA0', + opacity: 0.8, + }, + }, + contextMenu: { + color: '#575757', + colorDisabled: '#BABABA', + background: '#FFFFFF', + backgroundHover: '#D2D2D6', + }, + input: { + color: '#000000', + background: '#FFFFFF', + backgroundHover: '#E5E5EA', + backgroundActive: 'rgba(0, 0, 0, .2)', + }, + nav: { + color: '#000000', + }, + popover: { + color: '#000000', + background: '#FFFFFF', + }, + slider: { + background: '#3C3F43', + progressBar: '#888E94', + }, + spinner: { + background: 'rgba(0, 0, 0, 0.3)', + foreground: '#285DA0', + }, + table: { + selectedRow: '#CCCCCC', + }, + tag: { + background: '#DFDFE2', + text: '#000000', + }, + tooltip: { + color: '#000000', + background: '#FFFFFF', + }, + }, + other: { + button: { + borderRadius: '0px', + }, + coverArtFilter: 'drop-shadow(0px 3px 5px #000000)', + card: { + borderRadius: '0px', + }, + input: { + borderRadius: '0px', + }, + miniPlayer: { + height: '450px', + opacity: 0.95, + }, + panel: { + borderRadius: '0px', + }, + playerBar: { + borderTop: '1px solid rgba(240, 240, 240, .15)', + borderRight: 'none', + borderBottom: 'none', + borderLeft: 'none', + filter: 'none', + }, + tag: { + borderRadius: '0px', + }, + tooltip: { + border: '1px #3c3f43 solid', + borderRadius: '0px', + }, + }, + }, + ]); + } }; export default setDefaultSettings; diff --git a/src/components/shared/styled.ts b/src/components/shared/styled.ts index a69e8d4..8b11c7f 100644 --- a/src/components/shared/styled.ts +++ b/src/components/shared/styled.ts @@ -13,6 +13,8 @@ import { InputPicker, Popover, Panel, + TagPicker, + Tag, } from 'rsuite'; import styled from 'styled-components'; @@ -22,31 +24,121 @@ export const HeaderButton = styled(Button)` `; export const StyledButton = styled(Button)<{ width: number }>` + border-radius: ${(props) => props.theme.other.button.borderRadius} !important; background: ${(props) => - props.appearance === 'primary' ? `${props.theme.primary.main} !important` : undefined}; + props.appearance === 'primary' + ? `${props.theme.colors.primary}` + : props.appearance === 'subtle' || props.appearance === 'link' + ? undefined + : `${props.theme.colors.button.default.background}`} !important; + color: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.color}` + : props.appearance === 'subtle' + ? `${props.theme.colors.button.subtle.color}` + : props.appearance === 'link' + ? `${props.theme.colors.button.link.color}` + : `${props.theme.colors.button.default.color}`} !important; width: ${(props) => `${props.width}px`}; + + &:active, + &:focus, + &:hover { + text-decoration: none; + color: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.colorHover}` + : props.appearance === 'subtle' + ? `${props.theme.colors.button.subtle.colorHover}` + : props.appearance === 'link' + ? `${props.theme.colors.button.link.colorHover}` + : `${props.theme.colors.button.default.colorHover}`} !important; + + background: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.backgroundHover}` + : props.appearance === 'subtle' + ? `${props.theme.colors.button.subtle.backgroundHover}` + : props.appearance === 'link' + ? undefined + : `${props.theme.colors.button.default.backgroundHover}`} !important; + } `; export const StyledInputGroup = styled(InputGroup)` - input { - background-color: ${(props) => props.theme.primary.inputBackground}; - color: ${(props) => `${props.theme.primary.text} !important`}; + border-radius: ${(props) => props.theme.other.input.borderRadius}; +`; + +export const StyledInputGroupButton = styled(InputGroup.Button)` + background: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.primary}` + : props.appearance === 'subtle' || props.appearance === 'link' + ? undefined + : `${props.theme.colors.button.default.background}`} !important; + color: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.color}` + : props.appearance === 'subtle' + ? `${props.theme.colors.button.subtle.color}` + : props.appearance === 'link' + ? 'none' + : `${props.theme.colors.button.default.color}`} !important; + + &:active, + &:focus, + &:hover { + background: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.backgroundHover}` + : props.appearance === 'subtle' || props.appearance === 'link' + ? `none !important` + : `${props.theme.colors.button.default.backgroundHover} !important`}; + } + + &:hover { + color: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.colorHover}` + : props.appearance !== 'subtle' + ? `${props.theme.colors.button.default.colorHover}` + : `${props.theme.colors.button.subtle.colorHover} !important`}; } + border-radius: ${(props) => props.theme.other.input.borderRadius}; + border-bottom-right-radius: ${(props) => props.theme.other.input.borderRadius} !important; + border-top-right-radius: ${(props) => props.theme.other.input.borderRadius} !important; `; export const StyledInputNumber = styled(InputNumber)<{ width: number }>` + border: 1px #3c3f43 solid !important; + border-radius: ${(props) => props.theme.other.input.borderRadius} !important; + input { - background-color: ${(props) => props.theme.primary.inputBackground}; + background-color: ${(props) => props.theme.colors.input.background}; + } + + .rs-input { + border-radius: ${(props) => props.theme.other.input.borderRadius} !important; } + + &:hover, + &:active, + &:focus { + border-color: ${(props) => props.theme.colors.primary} !important; + } + width: ${(props) => `${props.width}px`}; `; export const StyledInput = styled(Input)<{ width: number }>` - input { - background-color: ${(props) => props.theme.primary.inputBackground}; - } + border: 1px #3c3f43 solid; + border-radius: ${(props) => props.theme.other.input.borderRadius} !important; + + color: ${(props) => props.theme.colors.input.color} !important; + background: ${(props) => props.theme.colors.input.background} !important; width: ${(props) => `${props.width}px`}; + border-radius: ${(props) => props.theme.other.input.borderRadius}; `; export const StyledCheckbox = styled(Checkbox)` @@ -54,12 +146,12 @@ export const StyledCheckbox = styled(Checkbox)` label { span { &:before { - border: ${(props) => `1px solid ${props.theme.primary.main}`}; + border: ${(props) => `1px solid ${props.theme.colors.primary}`}; } span { &:before { background-color: ${(props) => - props.defaultChecked ? `${props.theme.primary.main} !important` : undefined}; + props.defaultChecked ? `${props.theme.colors.primary} !important` : undefined}; } &:after { border: transparent !important; @@ -79,7 +171,7 @@ export const StyledRadio = styled(Radio)` background-color: transparent !important; } &:after { - background: ${(props) => `${props.theme.primary.main} !important`}; + background: ${(props) => `${props.theme.colors.primary} !important`}; } } } @@ -88,39 +180,62 @@ export const StyledRadio = styled(Radio)` `; export const StyledIconButton = styled(IconButton)` + border-radius: ${(props) => props.theme.other.button.borderRadius} !important; + background: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.primary}` + : props.appearance === 'subtle' || props.appearance === 'link' + ? undefined + : `${props.theme.colors.button.default.background}`}; + color: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.color}` + : props.appearance === 'subtle' + ? `${props.theme.colors.button.subtle.color}` + : props.appearance === 'link' + ? undefined + : `${props.theme.colors.button.default.color}`}; + + width: ${(props) => `${props.width}px`}; + + &:active, + &:focus, &:hover { + color: ${(props) => + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.colorHover}` + : props.appearance !== 'subtle' + ? `${props.theme.colors.button.default.colorHover}` + : `${props.theme.colors.button.subtle.colorHover}`}; + background: ${(props) => - props.appearance === 'subtle' ? 'transparent !important' : undefined}; - color: ${(props) => (props.appearance === 'subtle' ? props.theme.primary.main : undefined)}; - } - &:focus { - background: ${(props) => - props.appearance === 'subtle' ? 'transparent !important' : undefined}; - color: ${(props) => (props.appearance === 'subtle' ? props.theme.primary.main : undefined)}; + props.appearance === 'primary' + ? `${props.theme.colors.button.primary.backgroundHover}` + : props.appearance === 'subtle' + ? `${props.theme.colors.button.subtle.backgroundHover}` + : props.appearance === 'link' + ? undefined + : `${props.theme.colors.button.default.backgroundHover}`}; } - background-color: ${(props) => - props.appearance === 'primary' ? props.theme.primary.main : undefined}; - width: ${(props) => `${props.width}px`}; `; export const StyledNavItem = styled(Nav.Item)` a { - color: ${(props) => (props.active ? `${props.theme.primary.main} !important;` : undefined)}; - - &:hover { - color: ${(props) => `${props.theme.primary.main} !important;`}; - } + color: ${(props) => + props.active + ? `${props.theme.colors.primary} !important` + : `${props.theme.colors.nav.color} !important`}; } `; export const StyledIconToggle = styled(Icon)<{ active: string }>` cursor: pointer; color: ${(props) => - props.active === 'true' ? props.theme.primary.main : props.theme.primary.text}; + props.active === 'true' ? props.theme.colors.primary : props.theme.colors.layout.page.color}; `; export const StyledRate = styled(Rate)` - color: ${(props) => props.theme.primary.main}; + color: ${(props) => props.theme.colors.primary}; `; export const StyledSlider = styled(Slider)` @@ -131,20 +246,111 @@ export const StyledSlider = styled(Slider)` } `; +export const StyledInputPickerContainer = styled.div` + .rs-picker-menu { + background: ${(props) => props.theme.colors.input.background}; + border-radius: ${(props) => props.theme.other.input.borderRadius}; + } + + .rs-picker-select-menu-item-active { + background: ${(props) => props.theme.colors.input.backgroundActive}; + + &:hover { + background: ${(props) => props.theme.colors.input.backgroundActive}; + } + } + + .rs-picker-select-menu-item-focus { + color: ${(props) => props.theme.colors.input.color}; + background: ${(props) => props.theme.colors.input.backgroundHover}; + } + + .rs-picker-select-menu-item, + .rs-picker-select-menu-group-title { + color: ${(props) => props.theme.colors.input.color}; + + &:hover { + color: ${(props) => props.theme.colors.input.color}; + &:hover { + background: ${(props) => props.theme.colors.input.backgroundHover}; + } + } + } + + .rs-picker-select-menu-group-title { + color: ${(props) => props.theme.colors.input.color}; + + &:hover { + color: ${(props) => props.theme.colors.input.color}; + } + } + + .rs-check-item { + background: ${(props) => props.theme.colors.input.background} !important; + border-radius: ${(props) => props.theme.other.input.borderRadius}; + + &:hover { + color: ${(props) => props.theme.colors.input.color}; + background-color: ${(props) => props.theme.colors.input.backgroundHover} !important; + } + } + + .rs-check-item-focus { + color: ${(props) => props.theme.colors.input.color}; + background: ${(props) => props.theme.colors.input.backgroundActive} !important; + } + + .rs-checkbox-checked { + .rs-checkbox-checker { + span { + &:before { + border: ${(props) => `1px solid ${props.theme.colors.primary}`}; + } + span { + &:before { + background-color: ${(props) => `${props.theme.colors.primary} !important`}; + } + &:after { + border: transparent !important; + } + } + } + } + } +`; + export const StyledInputPicker = styled(InputPicker)<{ width?: number }>` + border: 1px #3c3f43 solid !important; + border-radius: ${(props) => props.theme.other.input.borderRadius} !important; + + &:hover, + &:active, + &:focus { + border-color: ${(props) => props.theme.colors.primary} !important; + } + .rs-picker-toggle-value { - color: ${(props) => `${props.theme.primary.text} !important`}; + color: ${(props) => `${props.theme.colors.layout.page.color} !important`}; + } + + .rs-picker-toggle { + border-radius: ${(props) => props.theme.other.input.borderRadius}; + } + + .rs-picker-select-menu-item { + background: ${(props) => `${props.theme.colors.background.input} !important`}; } .rs-btn-default { - background: ${(props) => `${props.theme.primary.inputBackground} !important`}; + background: ${(props) => `${props.theme.colors.input.background} !important`}; } width: ${(props) => `${props.width}px`}; + border-radius: ${(props) => props.theme.other.input.borderRadius}; `; export const StyledIcon = styled(Icon)` - color: ${(props) => `${props.theme.primary.main} !important`}; + color: ${(props) => `${props.theme.colors.primary} !important`}; `; export const ContextMenuWindow = styled.div<{ @@ -155,6 +361,7 @@ export const ContextMenuWindow = styled.div<{ width: number; hasTitle: boolean; }>` + background: ${(props) => props.theme.colors.contextMenu.background}; position: absolute; top: ${(props) => `${props.yPos}px`}; left: ${(props) => `${props.xPos}px`}; @@ -166,12 +373,22 @@ export const ContextMenuWindow = styled.div<{ overflow: hidden; overflow-x: hidden; font-size: smaller; - background: ${(props) => props.theme.primary.sideBar}; border: 1px #3c4043 solid; z-index: 2000; `; export const StyledContextMenuButton = styled(Button)` + color: ${(props) => + props.disabled + ? props.theme.colors.contextMenu.colorDisabled + : props.theme.colors.contextMenu.color} !important; + &:hover, + &:active, + &:focus { + color: ${(props) => props.theme.colors.contextMenu.color}; + background: ${(props) => props.theme.colors.contextMenu.backgroundHover}; + } + text-align: left; margin: 0px !important; border-radius: 0px !important; @@ -182,14 +399,23 @@ export const ContextMenuDivider = styled.hr` `; export const ContextMenuTitle = styled.div` - color: ${(props) => props.theme.primary.text}; + color: ${(props) => props.theme.colors.layout.page.color}; margin: 5px 0 5px 5px; user-select: none; `; +export const ContextMenuPopover = styled(Popover)` + color: ${(props) => props.theme.colors.contextMenu.color} !important; + background: ${(props) => props.theme.colors.contextMenu.background}; + position: absolute; + z-index: 1000; +`; + export const StyledPopover = styled(Popover)` + color: ${(props) => props.theme.colors.popover.color}; + background: ${(props) => props.theme.colors.popover.background}; position: absolute; - z-index: 2; + z-index: 1000; `; export const SectionTitleWrapper = styled.div` @@ -199,26 +425,62 @@ export const SectionTitleWrapper = styled.div` export const SectionTitle = styled.a` font-size: 20px; - color: ${(props) => props.theme.primary.text}; + color: ${(props) => props.theme.colors.layout.page.color}; + cursor: ${(props) => (props.onClick ? 'pointer' : 'default')}; &:hover { - cursor: ${(props) => (props.onClick ? 'pointer' : 'default')}; text-decoration: none; - color: ${(props) => (!props.onClick ? props.theme.primary.text : undefined)}; + color: ${(props) => + !props.onClick ? props.theme.colors.layout.page.color : props.theme.colors.primary}; } &:active, &:focus { text-decoration: none; - color: ${(props) => (!props.onClick ? props.theme.primary.text : undefined)}; + color: ${(props) => + !props.onClick ? props.theme.colors.layout.page.color : props.theme.colors.primary}; } `; export const StyledLink = styled.a` - color: ${(props) => props.theme.primary.text}; + color: ${(props) => props.theme.colors.layout.page.color}; cursor: pointer; + &:hover { + text-decoration: none; + color: ${(props) => props.theme.colors.button.link.colorHover}; + } `; export const StyledPanel = styled(Panel)` - color: ${(props) => props.theme.primary.text}; + color: ${(props) => props.theme.colors.layout.page.color}; + border-radius: ${(props) => props.theme.other.panel.borderRadius}; +`; + +export const StyledTagPicker = styled(TagPicker)` + border: 1px #3c3f43 solid !important; + border-radius: ${(props) => props.theme.other.input.borderRadius} !important; + + &:hover, + &:active, + &:focus { + border-color: ${(props) => props.theme.colors.primary} !important; + } + + .rs-picker-input { + &:hover { + border-color: ${(props) => props.theme.colors.primary}; + } + } + + .rs-tag { + color: ${(props) => props.theme.colors.tag.text}; + background: ${(props) => props.theme.colors.tag.background}; + border-radius: ${(props) => props.theme.other.tag.borderRadius}; + } +`; + +export const StyledTag = styled(Tag)` + color: ${(props) => props.theme.colors.tag.text}; + background: ${(props) => props.theme.colors.tag.background}; + border-radius: ${(props) => props.theme.other.tag.borderRadius}; `; diff --git a/src/components/viewtypes/ListViewTable.tsx b/src/components/viewtypes/ListViewTable.tsx index dc34a7b..25f0488 100644 --- a/src/components/viewtypes/ListViewTable.tsx +++ b/src/components/viewtypes/ListViewTable.tsx @@ -45,13 +45,13 @@ import { setActive } from '../../redux/albumSlice'; const StyledTable = styled(Table)<{ rowHeight: number; $isDragging: boolean }>` .rs-table-row.selected { - background: ${(props) => props.theme.primary.rowSelected} !important; + background: ${(props) => props.theme.colors.table.selectedRow} !important; // Resolve bug from rsuite-table where certain scrollpoints show a horizontal border height: ${(props) => `${props.rowHeight + 1}px !important`}; } .rs-table-row.dragover { - box-shadow: ${(props) => `inset 0px 5px 0px -3px ${props.theme.primary.main}`}; + box-shadow: ${(props) => `inset 0px 5px 0px -3px ${props.theme.colors.primary}`}; } .rs-table-row, diff --git a/src/components/viewtypes/styled.tsx b/src/components/viewtypes/styled.tsx index 6e28605..3a52956 100644 --- a/src/components/viewtypes/styled.tsx +++ b/src/components/viewtypes/styled.tsx @@ -12,14 +12,16 @@ export const RsuiteLinkButton = styled(Button)<{ overflow: hidden; color: ${(props) => props.playing === 'true' - ? props.theme.primary.main + ? props.theme.colors.primary : props.subtitle === 'true' - ? props.theme.secondary.text - : props.theme.primary.text}; + ? props.theme.colors.layout.page.colorSecondary + : props.theme.colors.layout.page.color}; - &:hover { + &:hover, + &:active, + &:focus { text-decoration: underline; - color: ${(props) => props.theme.primary.text}; + color: ${(props) => props.theme.colors.layout.page.color} !important; cursor: pointer; } `; @@ -30,14 +32,14 @@ export const TableCellWrapper = styled.div<{ dragover?: string; dragfield?: string; }>` - color: ${(props) => (props.playing === 'true' ? props.theme.primary.main : undefined)}; + color: ${(props) => (props.playing === 'true' ? props.theme.colors.primary : undefined)}; line-height: ${(props) => (props.height ? `${props.height}px` : undefined)}; cursor: ${(props) => props.dragover === 'true' ? 'grabbing' : props.dragfield === 'true' ? 'grab' : 'default'}; `; export const CombinedTitleTextWrapper = styled.span<{ playing: string }>` - color: ${(props) => (props.playing === 'true' ? props.theme.primary.main : undefined)}; + color: ${(props) => (props.playing === 'true' ? props.theme.colors.primary : undefined)}; `; export const StyledTableHeaderCell = styled(Table.HeaderCell)` @@ -55,6 +57,6 @@ export const StyledTableHeaderCell = styled(Table.HeaderCell)` .rs-table-cell-header-icon-sort-desc::after, .rs-table-cell-header-icon-sort-asc::after { - color: ${(props) => `${props.theme.primary.main} !important`}; + color: ${(props) => `${props.theme.colors.primary} !important`}; } `; diff --git a/src/styles/custom-theme.less b/src/styles/custom-theme.less index f8d0dc5..c0e24ab 100644 --- a/src/styles/custom-theme.less +++ b/src/styles/custom-theme.less @@ -60,3 +60,9 @@ // Tooltip @tooltip-bg: transparent; @tooltip-color: transparent; + +// Popover +@popover-arrow-width: 0px; + +@input-border-focus: #3c3f43; +@input-border: undefined; diff --git a/src/styles/styledTheme.ts b/src/styles/styledTheme.ts index a0359f9..3313374 100644 --- a/src/styles/styledTheme.ts +++ b/src/styles/styledTheme.ts @@ -1,61 +1,286 @@ export const defaultDark = { - all: { - fonts: { - pageTitleFontSize: '30px', - pageFontSize: '14px', - panelHeaderFontSize: '20px', + label: 'Default Dark', + value: 'defaultDark', + fonts: { + size: { + page: '14px', + pageTitle: '40px', + panelTitle: '20px', + button: '14px', }, }, - primary: { - main: '#2196F3', - background: '#181a1f', - titleBar: '#101010', - titleText: '#FFFFFF', - playerBar: '#101010', - sideBar: '#101010', - text: '#D8D8D8', - rowSelected: '#4D5156', - playerBarText: '#e9ebf0', - playerBarButtons: 'rgba(240, 240, 240, 0.8)', - playerBarButtonsHover: '#ffffff', - inputBackground: '#1A1D24', - spinner: '#FFFFFF', - spinnerBackground: 'rgba(233, 235, 240, 0.3)', - sliderBackground: '#888E94', - coverArtShadow: '#000000', + colors: { + primary: '#2196F3', + layout: { + page: { + color: '#D8D8D8', + colorSecondary: '#888e94', + background: '#181A1F', + }, + playerBar: { + color: '#D8D8D8', + colorSecondary: '#888e94', + background: '#101010', + button: { + color: 'rgba(240, 240, 240, 0.8)', + colorHover: '#FFFFFF', + }, + }, + sideBar: { + background: '#101010', + button: { + color: '#D8D8D8', + colorHover: '#FFFFFF', + }, + }, + titleBar: { + color: '#FFFFFF', + background: '#101010', + }, + }, + button: { + default: { + color: '#D8D8D8', + colorHover: '#FFFFFF', + background: '#292D33', + backgroundHover: '#3C3F43', + }, + primary: { + color: '#FFFFFF', + colorHover: '#FFFFFF', + backgroundHover: '#3B89EC', + }, + subtle: { + color: '#D8D8D8', + colorHover: '#D8D8D8', + backgroundHover: 'transparent', + }, + link: { + color: '#2196F3', + colorHover: '#3B89EC', + }, + }, + card: { + overlayButton: { + color: '#FFFFFF', + background: '#000000', + opacity: 0.8, + }, + }, + contextMenu: { + color: '#D8D8D8', + colorDisabled: '#6A6F76', + background: '#1E2125', + backgroundHover: '#292D33', + }, + input: { + color: '#D8D8D8', + background: '#25292E', + backgroundHover: '#353A45', + backgroundActive: 'rgba(240, 240, 240, .2)', + }, + nav: { + color: '#D8D8D8', + }, + popover: { + color: '#D8D8D8', + background: '#1E2125', + }, + slider: { + background: '#3C3F43', + progressBar: '#888E94', + }, + spinner: { + background: 'rgba(233, 235, 240, 0.3)', + foreground: '#2196F3', + }, + table: { + selectedRow: '#4D5156', + }, + tag: { + background: '#3C3F43', + text: '#E2E4E9', + }, + tooltip: { + color: '#D8D8D8', + background: '#1E2125', + }, }, - secondary: { - main: '#292D33', - text: '#888e94', - playerBarText: '#888e94', + other: { + button: { + borderRadius: '0px', + }, + coverArtFilter: 'drop-shadow(0px 3px 5px #000000)', + card: { + borderRadius: '0px', + }, + input: { + borderRadius: '0px', + }, + miniPlayer: { + height: '450px', + opacity: 0.95, + }, + panel: { + borderRadius: '0px', + }, + playerBar: { + borderTop: '1px solid rgba(240, 240, 240, .15)', + borderRight: 'none', + borderBottom: 'none', + borderLeft: 'none', + filter: 'none', + }, + tag: { + borderRadius: '0px', + }, + tooltip: { + border: '1px #3c3f43 solid', + borderRadius: '0px', + }, }, }; export const defaultLight = { - all: { - ...defaultDark.all, + label: 'Default Light', + value: 'defaultLight', + fonts: { + size: { + page: '14px', + pageTitle: '30px', + panelTitle: '20px', + }, }, - primary: { - main: '#285DA0', - background: '#EBEEF5', - titleBar: '#21252B', - titleText: '#FFFFFF', - playerBar: '#21252B', - sideBar: '#21252B', - text: '#000000', - rowSelected: '#BABCC2', - playerBarText: '#EBEEF5', - playerBarButtons: 'rgba(240, 240, 240, 0.8)', - playerBarButtonsHover: '#FFFFFF', - inputBackground: '#F4F7FF', - spinner: '#000000', - spinnerBackground: 'rgba(0, 0, 0, 0.3)', - sliderBackground: '#888e94', - coverArtShadow: '#000000', + colors: { + primary: '#285DA0', + layout: { + page: { + color: '#000000', + colorSecondary: '#888e94', + background: '#FFFFFF', + }, + playerBar: { + color: '#FFFFFF', + colorSecondary: '#888e94', + background: '#161B22', + button: { + color: 'rgba(240, 240, 240, 0.8)', + colorHover: '#FFFFFF', + }, + }, + sideBar: { + background: '#161B22', + button: { + color: '#D8D8D8', + colorHover: '#FFFFFF', + }, + }, + titleBar: { + color: '#FFFFFF', + background: '#161B22', + }, + }, + button: { + default: { + color: '#575757', + colorHover: '#000000', + background: '#DFDFE2', + backgroundHover: '#D2D2D6', + }, + primary: { + color: '#FFFFFF', + colorHover: '#FFFFFF', + backgroundHover: '#347AD3', + }, + subtle: { + color: '#575757', + colorHover: '#575757', + backgroundHover: 'transparent', + }, + link: { + color: '#575757', + colorHover: '#575757', + }, + }, + card: { + overlayButton: { + color: '#FFFFFF', + colorHover: '#FFFFFF', + background: '#000000', + backgroundHover: '#285DA0', + opacity: 0.8, + }, + }, + contextMenu: { + color: '#575757', + colorDisabled: '#BABABA', + background: '#FFFFFF', + backgroundHover: '#D2D2D6', + }, + input: { + color: '#000000', + background: '#FFFFFF', + backgroundHover: '#E5E5EA', + backgroundActive: 'rgba(0, 0, 0, .2)', + }, + nav: { + color: '#000000', + }, + popover: { + color: '#000000', + background: '#FFFFFF', + }, + slider: { + background: '#3C3F43', + progressBar: '#888E94', + }, + spinner: { + background: 'rgba(0, 0, 0, 0.3)', + foreground: '#285DA0', + }, + table: { + selectedRow: '#CCCCCC', + }, + tag: { + background: '#DFDFE2', + text: '#000000', + }, + tooltip: { + color: '#000000', + background: '#FFFFFF', + }, }, - secondary: { - main: '#292D33', - text: '#888e94', - playerBarText: '#888e94', + other: { + button: { + borderRadius: '0px', + }, + coverArtFilter: 'drop-shadow(0px 3px 5px #000000)', + card: { + borderRadius: '0px', + }, + input: { + borderRadius: '0px', + }, + miniPlayer: { + height: '450px', + opacity: 0.95, + }, + panel: { + borderRadius: '0px', + }, + playerBar: { + borderTop: '1px solid rgba(240, 240, 240, .15)', + borderRight: 'none', + borderBottom: 'none', + borderLeft: 'none', + filter: 'none', + }, + tag: { + borderRadius: '0px', + }, + tooltip: { + border: '1px #3c3f43 solid', + borderRadius: '0px', + }, }, };