Browse Source

Update theme template

master
jeffvli 3 years ago
committed by Jeff
parent
commit
cf91cc283a
  1. 33
      src/components/card/styled.tsx
  2. 15
      src/components/layout/GenericPageHeader.tsx
  3. 42
      src/components/layout/Sidebar.tsx
  4. 28
      src/components/layout/styled.tsx
  5. 14
      src/components/library/ArtistView.tsx
  6. 5
      src/components/loader/PageLoader.tsx
  7. 4
      src/components/modal/PageModal.tsx
  8. 81
      src/components/player/NowPlayingView.tsx
  9. 7
      src/components/player/PlayerBar.tsx
  10. 51
      src/components/player/styled.tsx
  11. 8
      src/components/playlist/PlaylistList.tsx
  12. 12
      src/components/playlist/PlaylistView.tsx
  13. 41
      src/components/scrollingmenu/ScrollingMenu.tsx
  14. 20
      src/components/settings/Config.tsx
  15. 63
      src/components/settings/ConfigPanels/CacheConfig.tsx
  16. 8
      src/components/settings/ConfigPanels/ListViewConfig.tsx
  17. 6
      src/components/settings/DisconnectButton.tsx
  18. 10
      src/components/settings/styled.tsx
  19. 150
      src/components/shared/ContextMenu.tsx
  20. 7
      src/components/shared/CustomTooltip.tsx
  21. 8
      src/components/shared/ToolbarButtons.tsx
  22. 289
      src/components/shared/setDefaultSettings.ts
  23. 342
      src/components/shared/styled.ts
  24. 4
      src/components/viewtypes/ListViewTable.tsx
  25. 18
      src/components/viewtypes/styled.tsx
  26. 6
      src/styles/custom-theme.less
  27. 323
      src/styles/styledTheme.ts

33
src/components/card/styled.tsx

@ -19,12 +19,12 @@ interface Card {
}; */
export const CardPanel = styled(Panel)<Card>`
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)<Card>`
`;
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<Card>`
@ -83,7 +95,6 @@ export const LazyCardImg = styled(LazyLoadImage)<Card>`
`;
export const Overlay = styled.div<Card>`
background-color: #1a1d24;
position: relative;
height: ${(props) => `${props.cardsize}px`};
width: ${(props) => `${props.cardsize}px`};
@ -93,7 +104,7 @@ export const Overlay = styled.div<Card>`
.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<Card>`
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};
}
`;

15
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 = ({
<InputGroup.Addon>
<Icon icon="search" />
</InputGroup.Addon>
<Input
<StyledInput
id="local-search-input"
value={searchQuery}
onChange={handleSearch}
@ -115,7 +120,7 @@ const GenericPageHeader = ({
}}
style={{ width: '180px' }}
/>
<InputGroup.Button
<StyledInputGroupButton
appearance="subtle"
onClick={() => {
clearSearchQuery();
@ -123,7 +128,7 @@ const GenericPageHeader = ({
}}
>
<Icon icon="close" />
</InputGroup.Button>
</StyledInputGroupButton>
</StyledInputGroup>
) : (
<StyledIconButton

42
src/components/layout/Sidebar.tsx

@ -1,6 +1,6 @@
import React from 'react';
import { Sidenav, Nav, Icon } from 'rsuite';
import { FixedSidebar } from './styled';
import { FixedSidebar, SidebarNavItem } from './styled';
const Sidebar = ({
expand,
@ -28,87 +28,87 @@ const Sidebar = ({
<Sidenav.Header />
<Sidenav.Body>
<Nav>
<Nav.Item
<SidebarNavItem
eventKey="discover"
icon={<Icon icon="dashboard" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Dashboard
</Nav.Item>
<Nav.Item
</SidebarNavItem>
<SidebarNavItem
eventKey="nowplaying"
icon={<Icon icon="music" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Now Playing
</Nav.Item>
<Nav.Item
</SidebarNavItem>
<SidebarNavItem
eventKey="playlists"
icon={<Icon icon="list-ul" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Playlists
</Nav.Item>
<Nav.Item
</SidebarNavItem>
<SidebarNavItem
eventKey="starred"
icon={<Icon icon="heart" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Favorites
</Nav.Item>
<Nav.Item
</SidebarNavItem>
<SidebarNavItem
eventKey="albums"
icon={<Icon icon="book2" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Albums
</Nav.Item>
<Nav.Item
</SidebarNavItem>
<SidebarNavItem
eventKey="artists"
icon={<Icon icon="people-group" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Artists
</Nav.Item>
<Nav.Item
</SidebarNavItem>
<SidebarNavItem
eventKey="genres"
icon={<Icon icon="globe2" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Genres
</Nav.Item>
<Nav.Item
</SidebarNavItem>
<SidebarNavItem
eventKey="folders"
icon={<Icon icon="folder-open" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Folders
</Nav.Item>
</SidebarNavItem>
</Nav>
<Nav>
<Nav.Item
<SidebarNavItem
eventKey="config"
icon={<Icon icon="gear-circle" />}
onSelect={handleSidebarSelect}
disabled={disableSidebar}
>
Config
</Nav.Item>
<Nav.Item
</SidebarNavItem>
<SidebarNavItem
icon={<Icon icon={expand ? 'arrow-left' : 'arrow-right'} />}
onSelect={handleToggle}
disabled={disableSidebar}
>
{expand ? 'Collapse' : 'Expand'}
</Nav.Item>
</SidebarNavItem>
</Nav>
</Sidenav.Body>
</Sidenav>

28
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};
`;

14
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={
<Popover style={{ width: '400px' }}>
<StyledPopover style={{ width: '400px' }}>
<div>
<h6>Related artists</h6>
<TagGroup>
{artistInfo.similarArtist?.map((artist: any) => (
<Tag key={artist.id}>
<StyledTag key={artist.id}>
<TagLink
onClick={() => {
if (!rest.isModal) {
@ -235,7 +235,7 @@ const ArtistView = ({ ...rest }: any) => {
>
{artist.name}
</TagLink>
</Tag>
</StyledTag>
))}
</TagGroup>
</div>
@ -247,10 +247,10 @@ const ArtistView = ({ ...rest }: any) => {
>
View on Last.FM
</StyledButton>
</Popover>
</StyledPopover>
}
>
<Button size="md">Info</Button>
<StyledButton size="md">Info</StyledButton>
</Whisper>
</ButtonToolbar>
</div>

5
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}`};
}
}
}

4
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 {

81
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<any>();
const pickerContainerRef = useRef(null);
const autoPlaylistTriggerRef = useRef<any>();
const dispatch = useAppDispatch();
const playQueue = useAppSelector((state) => state.playQueue);
@ -268,71 +269,66 @@ const NowPlayingView = () => {
speaker={
<StyledPopover>
<ControlLabel>How many tracks? (1-500)*</ControlLabel>
<StyledInputGroup>
<StyledInputNumber
min={1}
max={500}
step={10}
defaultValue={autoPlaylistTrackCount}
value={autoPlaylistTrackCount}
onChange={(e: number) => {
settings.setSync('randomPlaylistTrackCount', Number(e));
setRandomPlaylistTrackCount(Number(e));
}}
/>
</StyledInputGroup>
<StyledInputNumber
min={1}
max={500}
step={10}
defaultValue={autoPlaylistTrackCount}
value={autoPlaylistTrackCount}
onChange={(e: number) => {
settings.setSync('randomPlaylistTrackCount', Number(e));
setRandomPlaylistTrackCount(Number(e));
}}
/>
<br />
<FlexboxGrid justify="space-between">
<FlexboxGrid.Item>
<ControlLabel>From year</ControlLabel>
<div>
<StyledInputGroup>
<StyledInputNumber
width={100}
min={0}
max={3000}
step={1}
defaultValue={autoPlaylistFromYear}
value={autoPlaylistFromYear}
onChange={(e: number) => {
setRandomPlaylistFromYear(Number(e));
}}
/>
</StyledInputGroup>
<StyledInputNumber
width={100}
min={0}
max={3000}
step={1}
defaultValue={autoPlaylistFromYear}
value={autoPlaylistFromYear}
onChange={(e: number) => {
setRandomPlaylistFromYear(Number(e));
}}
/>
</div>
</FlexboxGrid.Item>
<FlexboxGrid.Item>
<ControlLabel>To year</ControlLabel>
<div>
<StyledInputGroup>
<StyledInputNumber
width={100}
min={0}
max={3000}
step={1}
defaultValue={autoPlaylistToYear}
value={autoPlaylistToYear}
onChange={(e: number) => setRandomPlaylistToYear(Number(e))}
/>
</StyledInputGroup>
<StyledInputNumber
width={100}
min={0}
max={3000}
step={1}
defaultValue={autoPlaylistToYear}
value={autoPlaylistToYear}
onChange={(e: number) => setRandomPlaylistToYear(Number(e))}
/>
</div>
</FlexboxGrid.Item>
</FlexboxGrid>
<br />
<ControlLabel>Genre</ControlLabel>
<div>
<StyledInputPickerContainer ref={pickerContainerRef}>
<StyledInputPicker
style={{ width: '100%' }}
container={() => pickerContainerRef.current}
data={genres}
value={randomPlaylistGenre}
virtualized
onChange={(e: string) => setRandomPlaylistGenre(e)}
/>
</div>
</StyledInputPickerContainer>
<br />
<ButtonToolbar>
<StyledButton
appearance="subtle"
onClick={() => handlePlayRandom('addNext')}
loading={isLoadingRandom}
disabled={!(typeof autoPlaylistTrackCount === 'number')}
@ -340,6 +336,7 @@ const NowPlayingView = () => {
<Icon icon="plus-circle" style={{ marginRight: '10px' }} /> Add (next)
</StyledButton>
<StyledButton
appearance="subtle"
onClick={() => handlePlayRandom('addLater')}
loading={isLoadingRandom}
disabled={!(typeof autoPlaylistTrackCount === 'number')}

7
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={
<Popover>
<StyledPopover>
<div style={{ height: '500px' }}>
<LazyLoadImage
src={
@ -341,7 +342,7 @@ const PlayerBar = () => {
height={500}
/>
</div>
</Popover>
</StyledPopover>
}
>
<LazyLoadImage

51
src/components/player/styled.tsx

@ -2,9 +2,13 @@ import { Icon, Slider } from 'rsuite';
import styled from 'styled-components';
export const PlayerContainer = styled.div`
background: ${(props) => 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;
`;

8
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={
<Popover>
<StyledPopover>
<Form>
<StyledInputGroup>
<Input
@ -123,7 +123,7 @@ const PlaylistList = () => {
Create
</StyledButton>
</Form>
</Popover>
</StyledPopover>
}
>
<AddPlaylistButton

12
src/components/playlist/PlaylistView.tsx

@ -3,7 +3,7 @@ import _ from 'lodash';
import fs from 'fs';
import path from 'path';
import settings from 'electron-settings';
import { ButtonToolbar, Form, Input, Popover, Whisper } from 'rsuite';
import { ButtonToolbar, Form, Input, Whisper } from 'rsuite';
import { useHotkeys } from 'react-hotkeys-hook';
import { useQuery, useQueryClient } from 'react-query';
import { useParams, useHistory } from 'react-router-dom';
@ -58,7 +58,7 @@ import GenericPageHeader from '../layout/GenericPageHeader';
import { setStatus } from '../../redux/playerSlice';
import { notifyToast } from '../shared/toast';
import { addProcessingPlaylist, removeProcessingPlaylist } from '../../redux/miscSlice';
import { StyledButton, StyledCheckbox, StyledInputGroup } from '../shared/styled';
import { StyledButton, StyledCheckbox, StyledInputGroup, StyledPopover } from '../shared/styled';
import {
moveToIndex,
removeFromPlaylist,
@ -414,7 +414,7 @@ const PlaylistView = ({ ...rest }) => {
placement="auto"
trigger="click"
speaker={
<Popover>
<StyledPopover>
<Form>
<StyledInputGroup>
<Input
@ -450,7 +450,7 @@ const PlaylistView = ({ ...rest }) => {
Edit
</StyledButton>
</Form>
</Popover>
</StyledPopover>
}
>
<EditButton size="md" disabled={misc.isProcessingPlaylist.includes(data?.id)} />
@ -461,12 +461,12 @@ const PlaylistView = ({ ...rest }) => {
placement="auto"
trigger="click"
speaker={
<Popover>
<StyledPopover>
<p>Are you sure you want to delete this playlist?</p>
<StyledButton onClick={handleDelete} appearance="link">
Yes
</StyledButton>
</Popover>
</StyledPopover>
}
>
<DeleteButton

41
src/components/scrollingmenu/ScrollingMenu.tsx

@ -41,7 +41,6 @@ const ScrollingMenu = ({
tabIndex={0}
onClick={onClickTitle}
onKeyDown={(e: any) => {
console.log(e);
if (e.key === ' ' || e.key === 'Enter') {
onClickTitle();
}
@ -51,24 +50,28 @@ const ScrollingMenu = ({
</SectionTitle>
</FlexboxGrid.Item>
<FlexboxGrid.Item>
<ButtonToolbar>
<ButtonGroup>
<StyledIconButton
icon={<Icon icon="arrow-left" />}
onClick={() => {
scrollContainerRef.current.scrollLeft -=
config.lookAndFeel.gridView.cardSize * 5;
}}
/>
<StyledIconButton
icon={<Icon icon="arrow-right" />}
onClick={() => {
scrollContainerRef.current.scrollLeft +=
config.lookAndFeel.gridView.cardSize * 5;
}}
/>
</ButtonGroup>
</ButtonToolbar>
{data.length > 0 && (
<ButtonToolbar>
<ButtonGroup>
<StyledIconButton
appearance="subtle"
icon={<Icon icon="arrow-left" />}
onClick={() => {
scrollContainerRef.current.scrollLeft -=
config.lookAndFeel.gridView.cardSize * 5;
}}
/>
<StyledIconButton
appearance="subtle"
icon={<Icon icon="arrow-right" />}
onClick={() => {
scrollContainerRef.current.scrollLeft +=
config.lookAndFeel.gridView.cardSize * 5;
}}
/>
</ButtonGroup>
</ButtonToolbar>
)}
</FlexboxGrid.Item>
</FlexboxGrid>
</SectionTitleWrapper>

20
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={
<Popover title="Confirm">
<StyledPopover title="Confirm">
<div>Are you sure you want to reset your settings to default?</div>
<strong>WARNING: This will reload the application</strong>
<div>
<Button
<StyledButton
id="reset-submit-button"
size="sm"
onClick={() => {
setDefaultSettings(true);
window.location.reload();
}}
appearance="link"
appearance="primary"
>
Yes
</Button>
<strong>WARNING: This will reload the application</strong>
</StyledButton>
</div>
</Popover>
</StyledPopover>
}
>
<StyledButton size="sm">Reset defaults</StyledButton>
@ -133,7 +133,7 @@ const Config = () => {
enterable
preventOverflow
speaker={
<Popover>
<StyledPopover>
<>
Current version: {packageJson.version}
<br />
@ -165,7 +165,7 @@ const Config = () => {
View CHANGELOG
</StyledButton>
</>
</Popover>
</StyledPopover>
}
>
<StyledButton

63
src/components/settings/ConfigPanels/CacheConfig.tsx

@ -3,9 +3,18 @@ import settings from 'electron-settings';
import { shell } from 'electron';
import fs from 'fs';
import path from 'path';
import { InputGroup, Button, Tag, Message, Icon, ButtonToolbar, Whisper, Popover } from 'rsuite';
import { Message, Icon, ButtonToolbar, Whisper } from 'rsuite';
import { ConfigPanel } from '../styled';
import { StyledInput, StyledCheckbox, StyledInputGroup, StyledLink } from '../../shared/styled';
import {
StyledInput,
StyledCheckbox,
StyledInputGroup,
StyledLink,
StyledPopover,
StyledTag,
StyledButton,
StyledInputGroupButton,
} from '../../shared/styled';
import { getSongCachePath, getImageCachePath, getRootCachePath } from '../../../shared/utils';
import { notifyToast } from '../../shared/toast';
import { setMiscSetting } from '../../../redux/miscSlice';
@ -112,7 +121,7 @@ const CacheConfig = () => {
<>
<StyledInputGroup>
<StyledInput value={newCachePath} onChange={(e: string) => setNewCachePath(e)} />
<InputGroup.Button
<StyledInputGroupButton
onClick={() => {
const check = fs.existsSync(newCachePath);
if (check) {
@ -131,16 +140,16 @@ const CacheConfig = () => {
}}
>
<Icon icon="check" />
</InputGroup.Button>
<InputGroup.Button
</StyledInputGroupButton>
<StyledInputGroupButton
onClick={() => {
setIsEditingCachePath(false);
setErrorMessage('');
}}
>
<Icon icon="close" />
</InputGroup.Button>
<InputGroup.Button
</StyledInputGroupButton>
<StyledInputGroupButton
onClick={() => {
const defaultPath = path.join(path.dirname(settings.file()));
settings.setSync('cachePath', defaultPath);
@ -151,7 +160,7 @@ const CacheConfig = () => {
}}
>
Reset to default
</InputGroup.Button>
</StyledInputGroupButton>
</StyledInputGroup>
<p style={{ fontSize: 'smaller' }}>
*You will need to manually move any existing cached files to their new location.
@ -163,7 +172,7 @@ const CacheConfig = () => {
Location:{' '}
<div style={{ overflow: 'auto' }}>
<StyledLink onClick={() => shell.openPath(getRootCachePath())}>
{getRootCachePath()}
{getRootCachePath()} <Icon icon="external-link" />
</StyledLink>
</div>
</>
@ -177,9 +186,9 @@ const CacheConfig = () => {
}}
>
Songs{' '}
<Tag>
<StyledTag>
{songCacheSize} MB {imgCacheSize === 9999999 && '- Folder not found'}
</Tag>
</StyledTag>
</StyledCheckbox>
<StyledCheckbox
defaultChecked={cacheImages}
@ -189,41 +198,41 @@ const CacheConfig = () => {
}}
>
Images{' '}
<Tag>
<StyledTag>
{imgCacheSize} MB {imgCacheSize === 9999999 && '- Folder not found'}
</Tag>
</StyledTag>
</StyledCheckbox>
</div>
<br />
<ButtonToolbar>
<Button onClick={() => setIsEditingCachePath(true)}>Edit cache location</Button>
<StyledButton onClick={() => setIsEditingCachePath(true)}>Edit cache location</StyledButton>
<Whisper
trigger="click"
placement="autoVertical"
speaker={
<Popover>
<StyledPopover>
Which cache would you like to clear?
<ButtonToolbar>
<Button size="sm" onClick={handleClearSongCache}>
<StyledButton size="sm" onClick={handleClearSongCache}>
Songs
</Button>
<Button size="sm" onClick={() => handleClearImageCache('playlist')}>
</StyledButton>
<StyledButton size="sm" onClick={() => handleClearImageCache('playlist')}>
Playlist images
</Button>
<Button size="sm" onClick={() => handleClearImageCache('album')}>
</StyledButton>
<StyledButton size="sm" onClick={() => handleClearImageCache('album')}>
Album images
</Button>
<Button size="sm" onClick={() => handleClearImageCache('artist')}>
</StyledButton>
<StyledButton size="sm" onClick={() => handleClearImageCache('artist')}>
Artist images
</Button>
<Button size="sm" onClick={() => handleClearImageCache('folder')}>
</StyledButton>
<StyledButton size="sm" onClick={() => handleClearImageCache('folder')}>
Folder images
</Button>
</StyledButton>
</ButtonToolbar>
</Popover>
</StyledPopover>
}
>
<Button>Clear cache</Button>
<StyledButton>Clear cache</StyledButton>
</Whisper>
</ButtonToolbar>
</ConfigPanel>

8
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
<div style={{ width: '100%' }}>
<div>
<StyledPanel bordered bodyFill>
<TagPicker
<StyledTagPicker
data={columnPicker}
defaultValue={defaultColumns}
value={selectedColumns}
style={{ width: '100%' }}
onChange={(e) => {
onChange={(e: any) => {
const columns: any[] = [];
if (e) {
e.forEach((selected: string) => {

6
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 (
<Button onClick={handleDisconnect} size="sm">
<StyledButton onClick={handleDisconnect} size="sm">
Disconnect
</Button>
</StyledButton>
);
};

10
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;

150
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={
<StyledPopover>
<ContextMenuPopover style={{ width: '150px' }}>
<Grid fluid>
<Row>
<Col xs={12}>
<StyledButton onClick={handleMoveToTop} block>
<Icon icon="angle-double-up" />
</StyledButton>
</Col>
<Col xs={12}>
<StyledButton onClick={handleMoveUpOne} block>
<Icon icon="angle-up" />
</StyledButton>
</Col>
</Row>
<Row>
<Col xs={12}>
<StyledButton onClick={handleMoveToBottom} block>
<Icon icon="angle-double-down" />
</StyledButton>
</Col>
<Col xs={12}>
<StyledButton onClick={handleMoveDownOne} block>
<Icon icon="angle-down" />
</StyledButton>
</Col>
</Row>
</Grid>
<br />
<Form>
<StyledInputGroup>
<StyledInputNumber
@ -583,51 +614,7 @@ export const GlobalContextMenu = () => {
</StyledButton>
</StyledInputGroup>
</Form>
<Grid fluid>
<Row>
<Col xs={12}>
<StyledIconButton
icon={<Icon icon="angle-double-up" />}
onClick={handleMoveToTop}
block
>
Top
</StyledIconButton>
</Col>
<Col xs={12}>
<StyledIconButton
icon={<Icon icon="angle-up" />}
onClick={handleMoveUpOne}
block
>
Up
</StyledIconButton>
</Col>
</Row>
<Row>
<Col xs={12}>
<StyledIconButton
icon={<Icon icon="angle-double-down" />}
onClick={handleMoveToBottom}
block
>
Bottom
</StyledIconButton>
</Col>
<Col xs={12}>
<StyledIconButton
icon={<Icon icon="angle-down" />}
onClick={handleMoveDownOne}
block
>
Down
</StyledIconButton>
</Col>
</Row>
</Grid>
</StyledPopover>
</ContextMenuPopover>
}
>
<ContextMenuButton
@ -643,27 +630,31 @@ export const GlobalContextMenu = () => {
placement="autoHorizontalStart"
trigger="none"
speaker={
<StyledPopover>
<StyledInputGroup>
<StyledInputPicker
data={playlists}
placement="autoVerticalStart"
virtualized
labelKey="name"
valueKey="id"
width={200}
onChange={(e: any) => setSelectedPlaylistId(e)}
/>
<StyledButton
disabled={
!selectedPlaylistId || misc.isProcessingPlaylist.includes(selectedPlaylistId)
}
loading={misc.isProcessingPlaylist.includes(selectedPlaylistId)}
onClick={handleAddToPlaylist}
>
Add
</StyledButton>
</StyledInputGroup>
<ContextMenuPopover>
<StyledInputPickerContainer ref={playlistPickerContainerRef}>
<StyledInputGroup>
<StyledInputPicker
container={() => playlistPickerContainerRef.current}
data={playlists}
placement="autoVerticalStart"
virtualized
labelKey="name"
valueKey="id"
width={200}
onChange={(e: any) => setSelectedPlaylistId(e)}
/>
<StyledButton
disabled={
!selectedPlaylistId ||
misc.isProcessingPlaylist.includes(selectedPlaylistId)
}
loading={misc.isProcessingPlaylist.includes(selectedPlaylistId)}
onClick={handleAddToPlaylist}
>
Add
</StyledButton>
</StyledInputGroup>
</StyledInputPickerContainer>
<div>
<StyledButton
@ -676,14 +667,11 @@ export const GlobalContextMenu = () => {
{shouldCreatePlaylist && (
<Form>
<StyledInputGroup>
<Input
placeholder="Enter name..."
value={newPlaylistName}
onChange={(e) => setNewPlaylistName(e)}
/>
</StyledInputGroup>
<br />
<StyledInput
placeholder="Enter name..."
value={newPlaylistName}
onChange={(e: string) => setNewPlaylistName(e)}
/>
<StyledButton
size="sm"
type="submit"
@ -699,7 +687,7 @@ export const GlobalContextMenu = () => {
</StyledButton>
</Form>
)}
</StyledPopover>
</ContextMenuPopover>
}
>
<ContextMenuButton
@ -718,12 +706,12 @@ export const GlobalContextMenu = () => {
placement="autoHorizontalStart"
trigger="none"
speaker={
<StyledPopover>
<ContextMenuPopover>
<p>Are you sure you want to delete {multiSelect.selected?.length} playlist(s)?</p>
<StyledButton onClick={handleDeletePlaylist} appearance="link">
Yes
</StyledButton>
</StyledPopover>
</ContextMenuPopover>
}
>
<ContextMenuButton

7
src/components/shared/CustomTooltip.tsx

@ -3,10 +3,11 @@ import { Tooltip, Whisper } from 'rsuite';
import styled from 'styled-components';
const StyledTooltip = styled(Tooltip)`
border: 1px #3c3f43 solid;
.rs-tooltip-inner {
background-color: ${(props) => 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};
}
`;

8
src/components/shared/ToolbarButtons.tsx

@ -98,7 +98,9 @@ export const DownloadButton = ({ ...rest }) => {
export const ShuffleButton = ({ ...rest }) => {
return (
<CustomTooltip text="Shuffle queue" placement="bottom">
<StyledIconButton icon={<Icon icon="random" />} tabIndex={0} {...rest} />
<StyledButton tabIndex={0} {...rest}>
<Icon icon="random" />
</StyledButton>
</CustomTooltip>
);
};
@ -106,7 +108,9 @@ export const ShuffleButton = ({ ...rest }) => {
export const ClearQueueButton = ({ ...rest }) => {
return (
<CustomTooltip text="Clear queue" placement="bottom">
<StyledIconButton icon={<Icon icon="trash2" />} tabIndex={0} {...rest} />
<StyledButton tabIndex={0} {...rest}>
<Icon icon="trash2" />
</StyledButton>
</CustomTooltip>
);
};

289
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;

342
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};
`;

4
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,

18
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`};
}
`;

6
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;

323
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',
},
},
};

Loading…
Cancel
Save