diff --git a/src/renderer/components/dropdown-menu/index.tsx b/src/renderer/components/dropdown-menu/index.tsx index 0d7305d8..5e6bfe4f 100644 --- a/src/renderer/components/dropdown-menu/index.tsx +++ b/src/renderer/components/dropdown-menu/index.tsx @@ -73,7 +73,7 @@ const StyledMenuDropdown = styled(MantineMenu.Dropdown)` border-radius: var(--dropdown-menu-border-radius); filter: drop-shadow(0 0 5px rgb(0, 0, 0, 50%)); - *:first-child { + /* *:first-child { border-top-left-radius: var(--dropdown-menu-border-radius); border-top-right-radius: var(--dropdown-menu-border-radius); } @@ -81,7 +81,7 @@ const StyledMenuDropdown = styled(MantineMenu.Dropdown)` *:last-child { border-bottom-right-radius: var(--dropdown-menu-border-radius); border-bottom-left-radius: var(--dropdown-menu-border-radius); - } + } */ `; const StyledMenuDivider = styled(MantineMenu.Divider)` diff --git a/src/renderer/components/index.ts b/src/renderer/components/index.ts index 3b4660de..2d3f27b0 100644 --- a/src/renderer/components/index.ts +++ b/src/renderer/components/index.ts @@ -34,3 +34,4 @@ export * from './context-menu'; export * from './query-builder'; export * from './rating'; export * from './hover-card'; +export * from './option'; diff --git a/src/renderer/components/option/index.tsx b/src/renderer/components/option/index.tsx new file mode 100644 index 00000000..a4e90b5b --- /dev/null +++ b/src/renderer/components/option/index.tsx @@ -0,0 +1,32 @@ +import { ReactNode } from 'react'; +import { Flex, Group } from '@mantine/core'; + +export const Option = ({ children }: any) => { + return ( + + {children} + + ); +}; + +interface LabelProps { + children: ReactNode; +} + +const Label = ({ children }: LabelProps) => { + return {children}; +}; + +interface ControlProps { + children: ReactNode; +} + +const Control = ({ children }: ControlProps) => { + return {children}; +}; + +Option.Label = Label; +Option.Control = Control; diff --git a/src/renderer/components/virtual-table/table-config-dropdown.tsx b/src/renderer/components/virtual-table/table-config-dropdown.tsx index f2e3c0fd..1a21f5a8 100644 --- a/src/renderer/components/virtual-table/table-config-dropdown.tsx +++ b/src/renderer/components/virtual-table/table-config-dropdown.tsx @@ -1,11 +1,10 @@ import type { ChangeEvent } from 'react'; -import { Divider, Stack } from '@mantine/core'; import { MultiSelect } from '/@/renderer/components/select'; import { Slider } from '/@/renderer/components/slider'; import { Switch } from '/@/renderer/components/switch'; -import { Text } from '/@/renderer/components/text'; import { useSettingsStoreActions, useSettingsStore } from '/@/renderer/store/settings.store'; import { TableColumn, TableType } from '/@/renderer/types'; +import { Option } from '/@/renderer/components/option'; export const SONG_TABLE_COLUMNS = [ { label: 'Row Index', value: TableColumn.ROW_INDEX }, @@ -168,42 +167,49 @@ export const TableConfigDropdown = ({ type }: TableConfigDropdownProps) => { }; return ( - - - Table Columns - column.column)} - dropdownPosition="top" - width={300} - onChange={handleAddOrRemoveColumns} - /> - - - Row Height - - - - - - + <> + + + + + ); }; diff --git a/src/renderer/features/now-playing/components/play-queue.tsx b/src/renderer/features/now-playing/components/play-queue.tsx index 329faaf9..0a29c2c3 100644 --- a/src/renderer/features/now-playing/components/play-queue.tsx +++ b/src/renderer/features/now-playing/components/play-queue.tsx @@ -13,6 +13,7 @@ import { useAppStoreActions, useCurrentSong, useDefaultQueue, + usePlayerControls, usePreviousSong, useQueueControls, } from '/@/renderer/store'; @@ -53,6 +54,7 @@ export const PlayQueue = forwardRef(({ type }: QueueProps, ref: Ref) => { const tableConfig = useTableSettings(type); const [gridApi, setGridApi] = useState(); const playerType = usePlayerType(); + const { play } = usePlayerControls(); useEffect(() => { if (tableRef.current) { @@ -79,6 +81,8 @@ export const PlayQueue = forwardRef(({ type }: QueueProps, ref: Ref) => { if (playerType === PlaybackType.LOCAL) { mpvPlayer.setQueue(playerData); } + + play(); }; const handleDragStart = () => { @@ -160,7 +164,7 @@ export const PlayQueue = forwardRef(({ type }: QueueProps, ref: Ref) => { } }; - const rowClassRules = useMemo(() => { + const rowClassRules = useMemo(() => { return { 'current-song': (params) => { return params.data.uniqueId === currentSong?.uniqueId; @@ -205,11 +209,13 @@ export const PlayQueue = forwardRef(({ type }: QueueProps, ref: Ref) => { rowDragMultiRow autoFitColumns={tableConfig.autoFit} columnDefs={columnDefs} + deselectOnClickOutside={type === 'fullScreen'} getRowId={(data) => data.data.uniqueId} rowBuffer={50} rowClassRules={rowClassRules} rowData={queue} rowHeight={tableConfig.rowHeight || 40} + suppressCellFocus={type === 'fullScreen'} onCellContextMenu={handleContextMenu} onCellDoubleClicked={handleDoubleClick} onColumnMoved={handleColumnChange} diff --git a/src/renderer/features/player/components/full-screen-player-image.tsx b/src/renderer/features/player/components/full-screen-player-image.tsx new file mode 100644 index 00000000..16916173 --- /dev/null +++ b/src/renderer/features/player/components/full-screen-player-image.tsx @@ -0,0 +1,237 @@ +import { Flex, Stack, Group, Center } from '@mantine/core'; +import { useSetState } from '@mantine/hooks'; +import { AnimatePresence, HTMLMotionProps, motion, Variants } from 'framer-motion'; +import { useEffect } from 'react'; +import { RiAlbumFill } from 'react-icons/ri'; +import { generatePath } from 'react-router'; +import { Link } from 'react-router-dom'; +import styled from 'styled-components'; +import { QueueSong } from '/@/renderer/api/types'; +import { Badge, Text, TextTitle } from '/@/renderer/components'; +import { useFastAverageColor } from '/@/renderer/hooks'; +import { AppRoute } from '/@/renderer/router/routes'; +import { PlayerData, usePlayerData, usePlayerStore } from '/@/renderer/store'; + +const Image = styled(motion.img)` + position: absolute; + width: 100%; + max-width: 100%; + height: 100%; + max-height: 100%; + object-fit: cover; + border-radius: 5px; + box-shadow: 2px 2px 10px 2px rgba(0, 0, 0, 40%); +`; + +const ImageContainer = styled(motion.div)` + position: relative; + display: flex; + align-items: center; + height: 65%; + aspect-ratio: 1/1; +`; + +const imageVariants: Variants = { + closed: { + opacity: 0, + transition: { + duration: 0.8, + ease: 'linear', + }, + }, + initial: { + opacity: 0, + }, + open: (custom) => { + const { isOpen } = custom; + return { + opacity: isOpen ? 1 : 0, + transition: { + duration: 0.4, + ease: 'linear', + }, + }; + }, +}; + +const scaleImageUrl = (url?: string | null) => { + return url + ?.replace(/&size=\d+/, '&size=800') + .replace(/\?width=\d+/, '?width=800') + .replace(/&height=\d+/, '&height=800'); +}; + +const ImageWithPlaceholder = ({ ...props }: HTMLMotionProps<'img'>) => { + if (!props.src) { + return ( +
+ +
+ ); + } + + return ; +}; + +export const FullScreenPlayerImage = () => { + const { queue } = usePlayerData(); + const currentSong = queue.current; + const background = useFastAverageColor(queue.current?.imageUrl, true, 'dominant'); + const imageKey = `image-${background}`; + + const [imageState, setImageState] = useSetState({ + bottomImage: scaleImageUrl(queue.next?.imageUrl), + current: 0, + topImage: scaleImageUrl(queue.current?.imageUrl), + }); + + useEffect(() => { + const unsubSongChange = usePlayerStore.subscribe( + (state) => [state.current.song, state.actions.getPlayerData().queue], + (state) => { + const isTop = imageState.current === 0; + const queue = state[1] as PlayerData['queue']; + + const currentImageUrl = scaleImageUrl(queue.current?.imageUrl); + const nextImageUrl = scaleImageUrl(queue.next?.imageUrl); + + setImageState({ + bottomImage: isTop ? currentImageUrl : nextImageUrl, + current: isTop ? 1 : 0, + topImage: isTop ? nextImageUrl : currentImageUrl, + }); + }, + { equalityFn: (a, b) => (a[0] as QueueSong)?.id === (b[0] as QueueSong)?.id }, + ); + + return () => { + unsubSongChange(); + }; + }, [imageState, queue, setImageState]); + + return ( + + + + {imageState.current === 0 && ( + + )} + + + {imageState.current === 1 && ( + + )} + + + + + {currentSong?.name} + + + {currentSong?.album}{' '} + + {currentSong?.artists?.map((artist, index) => ( + + {index > 0 && ( + + • + + )} + + {artist.name} + + + ))} + + {currentSong?.container && ( + + {currentSong?.container} {currentSong?.bitRate} + + )} + {currentSong?.releaseYear && {currentSong?.releaseYear}} + + + + ); +}; diff --git a/src/renderer/features/player/components/full-screen-player-queue.tsx b/src/renderer/features/player/components/full-screen-player-queue.tsx new file mode 100644 index 00000000..6dcc4206 --- /dev/null +++ b/src/renderer/features/player/components/full-screen-player-queue.tsx @@ -0,0 +1,129 @@ +import { Stack, Group, Center, Box } from '@mantine/core'; +import { motion } from 'framer-motion'; +import { HiOutlineQueueList } from 'react-icons/hi2'; +import { RiFileMusicLine, RiFileTextLine, RiInformationFill } from 'react-icons/ri'; +import styled from 'styled-components'; +import { Button, TextTitle } from '/@/renderer/components'; +import { PlayQueue } from '/@/renderer/features/now-playing'; +import { + useFullScreenPlayerStore, + useFullScreenPlayerStoreActions, +} from '/@/renderer/store/full-screen-player.store'; + +const QueueContainer = styled.div` + position: relative; + display: flex; + height: 100%; + + .ag-theme-alpine-dark { + --ag-header-background-color: rgba(0, 0, 0, 0%) !important; + --ag-background-color: rgba(0, 0, 0, 0%) !important; + --ag-odd-row-background-color: rgba(0, 0, 0, 0%) !important; + } + + .ag-header { + display: none !important; + } +`; + +const ActiveTabIndicator = styled(motion.div)` + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 2px; + background: var(--main-fg); +`; + +export const FullScreenPlayerQueue = () => { + const { activeTab } = useFullScreenPlayerStore(); + const { setStore } = useFullScreenPlayerStoreActions(); + + const headerItems = [ + { + active: activeTab === 'queue', + icon: , + label: 'Up Next', + onClick: () => setStore({ activeTab: 'queue' }), + }, + { + active: activeTab === 'related', + icon: , + label: 'Related', + onClick: () => setStore({ activeTab: 'related' }), + }, + { + active: activeTab === 'lyrics', + icon: , + label: 'Lyrics', + onClick: () => setStore({ activeTab: 'lyrics' }), + }, + ]; + + return ( + + + {headerItems.map((item) => ( + + + {item.active ? : null} + + ))} + + {activeTab === 'queue' ? ( + + + + ) : activeTab === 'related' ? ( +
+ + + + COMING SOON + + +
+ ) : activeTab === 'lyrics' ? ( +
+ + + + COMING SOON + + +
+ ) : null} +
+ ); +}; diff --git a/src/renderer/features/player/components/full-screen-player.tsx b/src/renderer/features/player/components/full-screen-player.tsx new file mode 100644 index 00000000..057d4666 --- /dev/null +++ b/src/renderer/features/player/components/full-screen-player.tsx @@ -0,0 +1,194 @@ +import { useLayoutEffect, useRef } from 'react'; +import { Group } from '@mantine/core'; +import { useHotkeys } from '@mantine/hooks'; +import { Variants, motion } from 'framer-motion'; +import { RiArrowDownSLine, RiSettings3Line } from 'react-icons/ri'; +import { useLocation } from 'react-router'; +import styled from 'styled-components'; +import { Button, Option, Popover, Switch, TableConfigDropdown } from '/@/renderer/components'; +import { + useCurrentSong, + useFullScreenPlayerStore, + useFullScreenPlayerStoreActions, +} from '/@/renderer/store'; +import { useFastAverageColor } from '../../../hooks/use-fast-average-color'; +import { FullScreenPlayerImage } from '/@/renderer/features/player/components/full-screen-player-image'; +import { FullScreenPlayerQueue } from '/@/renderer/features/player/components/full-screen-player-queue'; + +const Container = styled(motion.div)` + z-index: 100; + display: flex; + justify-content: center; + padding: 2rem; +`; + +const ResponsiveContainer = styled.div` + display: flex; + flex-direction: column; + gap: 2rem; + width: 100%; + max-width: 2560px; + margin-top: 70px; + + .full-screen-player-image { + max-height: calc(35vh - 90px); + } + + @media screen and (min-width: 1080px) { + flex-direction: row; + + .full-screen-player-image { + max-height: calc(70vh - 90px); + } + } + + @media screen and (max-height: 800px) and (min-width: 1080px) { + .full-screen-player-image { + max-height: calc(50vh - 90px); + } + } +`; + +const BackgroundImageOverlay = styled.div` + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 100%; + height: 100%; + background: linear-gradient(180deg, rgba(20, 21, 23, 40%), var(--main-bg)); +`; + +const Controls = () => { + const { dynamicBackground, expanded } = useFullScreenPlayerStore(); + const { setStore } = useFullScreenPlayerStoreActions(); + + const handleToggleFullScreenPlayer = () => { + setStore({ expanded: !expanded }); + }; + + useHotkeys([['Escape', handleToggleFullScreenPlayer]]); + + return ( + <> + + + + + + + + + + + + + + ); +}; + +const containerVariants: Variants = { + closed: { + height: 'calc(100vh - 90px)', + position: 'absolute', + top: '100vh', + transition: { + duration: 0.5, + ease: 'easeInOut', + }, + width: '100vw', + y: -100, + }, + open: (custom) => { + const { dynamicBackground, background } = custom; + return { + background: dynamicBackground ? background : 'var(--main-bg)', + height: 'calc(100vh - 90px)', + left: 0, + position: 'absolute', + top: 0, + transition: { + background: { + duration: 1, + ease: 'easeInOut', + }, + delay: 0.1, + duration: 0.5, + ease: 'easeInOut', + }, + width: '100vw', + y: 0, + }; + }, +}; + +export const FullScreenPlayer = () => { + const { dynamicBackground } = useFullScreenPlayerStore(); + const { setStore } = useFullScreenPlayerStoreActions(); + + const location = useLocation(); + const isOpenedRef = useRef(null); + + useLayoutEffect(() => { + if (isOpenedRef.current !== null) { + setStore({ expanded: false }); + } + + isOpenedRef.current = true; + }, [location, setStore]); + + const currentSong = useCurrentSong(); + const background = useFastAverageColor(currentSong?.imageUrl, true, 'dominant'); + + return ( + + + {dynamicBackground && } + + + + + + ); +}; diff --git a/src/renderer/features/player/components/left-controls.tsx b/src/renderer/features/player/components/left-controls.tsx index ca7bebf1..4498fc0e 100644 --- a/src/renderer/features/player/components/left-controls.tsx +++ b/src/renderer/features/player/components/left-controls.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { MouseEvent } from 'react'; import { Center, Group } from '@mantine/core'; import { motion, AnimatePresence, LayoutGroup } from 'framer-motion'; import { RiArrowUpSLine, RiDiscLine, RiMore2Fill } from 'react-icons/ri'; @@ -6,7 +6,13 @@ import { generatePath, Link } from 'react-router-dom'; import styled from 'styled-components'; import { Button, Text } from '/@/renderer/components'; import { AppRoute } from '/@/renderer/router/routes'; -import { useAppStoreActions, useAppStore, useCurrentSong } from '/@/renderer/store'; +import { + useAppStoreActions, + useAppStore, + useCurrentSong, + useSetFullScreenPlayerStore, + useFullScreenPlayerStore, +} from '/@/renderer/store'; import { fadeIn } from '/@/renderer/styles'; import { LibraryItem } from '/@/renderer/api/types'; import { SONG_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items'; @@ -35,7 +41,7 @@ const MetadataStack = styled(motion.div)` overflow: hidden; `; -const Image = styled(motion(Link))` +const Image = styled(motion.div)` width: 60px; height: 60px; filter: drop-shadow(0 0 5px rgb(0, 0, 0, 100%)); @@ -75,6 +81,8 @@ const LineItem = styled.div<{ $secondary?: boolean }>` export const LeftControls = () => { const { setSidebar } = useAppStoreActions(); + const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); + const setFullScreenPlayerStore = useSetFullScreenPlayerStore(); const hideImage = useAppStore((state) => state.sidebar.image); const currentSong = useCurrentSong(); const title = currentSong?.name; @@ -87,6 +95,16 @@ export const LeftControls = () => { SONG_CONTEXT_MENU_ITEMS, ); + const handleToggleFullScreenPlayer = (e: MouseEvent) => { + e.stopPropagation(); + setFullScreenPlayerStore({ expanded: !isFullScreenPlayerExpanded }); + }; + + const handleToggleSidebarImage = (e: MouseEvent) => { + e.stopPropagation(); + setSidebar({ image: true }); + }; + return ( @@ -101,8 +119,9 @@ export const LeftControls = () => { animate={{ opacity: 1, scale: 1, x: 0 }} exit={{ opacity: 0, x: -50 }} initial={{ opacity: 0, x: -50 }} - to={AppRoute.NOW_PLAYING} + role="button" transition={{ duration: 0.3, ease: 'easeInOut' }} + onClick={handleToggleFullScreenPlayer} > {currentSong?.imageUrl ? ( { sx={{ position: 'absolute', right: 2, top: 2 }} tooltip={{ label: 'Expand', openDelay: 500 }} variant="default" - onClick={(e) => { - e.preventDefault(); - setSidebar({ image: true }); - }} + onClick={handleToggleSidebarImage} > ` +const ImageContainer = styled(motion.div)<{ height: string }>` position: relative; height: ${(props) => props.height}; @@ -112,6 +114,12 @@ export const Sidebar = () => { startIndex: 0, }); + const setFullScreenPlayerStore = useSetFullScreenPlayerStore(); + const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); + const expandFullScreenPlayer = () => { + setFullScreenPlayerStore({ expanded: !isFullScreenPlayerExpanded }); + }; + const cq = useContainerQuery({ sm: 300 }); return ( @@ -327,8 +335,9 @@ export const Sidebar = () => { exit={{ opacity: 0, y: 200 }} height={sidebar.leftWidth} initial={{ opacity: 0, y: 200 }} - to={AppRoute.NOW_PLAYING} + role="button" transition={{ duration: 0.3, ease: 'easeInOut' }} + onClick={expandFullScreenPlayer} > {upsizedImageUrl ? ( { tooltip={{ label: 'Collapse', openDelay: 500 }} variant="default" onClick={(e) => { - e.preventDefault(); + e.stopPropagation(); setSidebar({ image: false }); }} > diff --git a/src/renderer/layouts/default-layout.tsx b/src/renderer/layouts/default-layout.tsx index cef35eb6..69f4217e 100644 --- a/src/renderer/layouts/default-layout.tsx +++ b/src/renderer/layouts/default-layout.tsx @@ -11,10 +11,11 @@ import { DrawerPlayQueue, SidebarPlayQueue } from '/@/renderer/features/now-play import { Playerbar } from '/@/renderer/features/player'; import { Sidebar } from '/@/renderer/features/sidebar/components/sidebar'; import { AppRoute } from '/@/renderer/router/routes'; -import { useAppStore, useAppStoreActions } from '/@/renderer/store'; +import { useAppStore, useAppStoreActions, useFullScreenPlayerStore } from '/@/renderer/store'; import { useSettingsStore, useGeneralSettings } from '/@/renderer/store/settings.store'; import { PlaybackType } from '/@/renderer/types'; import { constrainSidebarWidth, constrainRightSidebarWidth } from '/@/renderer/utils'; +import { FullScreenPlayer } from '/@/renderer/features/player/components/full-screen-player'; if (!isElectron()) { useSettingsStore.getState().actions.setSettings({ @@ -84,7 +85,7 @@ const ResizeHandle = styled.div<{ right: ${(props) => props.placement === 'right' && 0}; bottom: ${(props) => props.placement === 'bottom' && 0}; left: ${(props) => props.placement === 'left' && 0}; - z-index: 100; + z-index: 90; width: 2px; height: 100%; background-color: var(--sidebar-handle-bg); @@ -147,6 +148,7 @@ export const DefaultLayout = ({ shell }: DefaultLayoutProps) => { location.pathname !== AppRoute.NOW_PLAYING; const showSideQueue = sidebar.rightExpanded && location.pathname !== AppRoute.NOW_PLAYING; + const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); const queueDrawerButtonVariants: Variants = { hidden: { @@ -259,6 +261,12 @@ export const DefaultLayout = ({ shell }: DefaultLayoutProps) => { > {!shell && ( <> + + {isFullScreenPlayerExpanded && } + ) => void; + }; +} + +export const useFullScreenPlayerStore = create()( + persist( + devtools( + immer((set, get) => ({ + actions: { + setStore: (data) => { + set({ ...get(), ...data }); + }, + }, + activeTab: 'queue', + expanded: false, + })), + { name: 'store_full_screen_player' }, + ), + { + merge: (persistedState, currentState) => { + return merge(currentState, persistedState); + }, + name: 'store_full_screen_player', + version: 1, + }, + ), +); + +export const useFullScreenPlayerStoreActions = () => + useFullScreenPlayerStore((state) => state.actions); + +export const useSetFullScreenPlayerStore = () => + useFullScreenPlayerStore((state) => state.actions.setStore); diff --git a/src/renderer/store/index.ts b/src/renderer/store/index.ts index 3a0dbf37..d41850d1 100644 --- a/src/renderer/store/index.ts +++ b/src/renderer/store/index.ts @@ -5,3 +5,4 @@ export * from './list.store'; export * from './playlist.store'; export * from './album-list-data.store'; export * from './album-artist-list-data.store'; +export * from './full-screen-player.store'; diff --git a/src/renderer/store/player.store.ts b/src/renderer/store/player.store.ts index e289c305..b82141cf 100644 --- a/src/renderer/store/player.store.ts +++ b/src/renderer/store/player.store.ts @@ -892,6 +892,12 @@ export const useDefaultQueue = () => usePlayerStore((state) => state.queue.defau export const useCurrentSong = () => usePlayerStore((state) => state.current.song); +export const usePlayerData = () => + usePlayerStore( + (state) => state.actions.getPlayerData(), + (a, b) => a.current.nextIndex === b.current.nextIndex, + ); + export const useCurrentPlayer = () => usePlayerStore((state) => state.current.player); export const useCurrentStatus = () => usePlayerStore((state) => state.current.status); diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index e6979cef..d9ec7a36 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -61,6 +61,7 @@ export interface SettingsState { }; tab: 'general' | 'playback' | 'view' | string; tables: { + fullScreen: DataTableProps; nowPlaying: DataTableProps; sideDrawerQueue: DataTableProps; sideQueue: DataTableProps; @@ -116,6 +117,25 @@ export const useSettingsStore = create()( tab: 'general', tables: { + fullScreen: { + autoFit: true, + columns: [ + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + { + column: TableColumn.USER_FAVORITE, + width: 100, + }, + ], + followCurrentSong: true, + rowHeight: 60, + }, nowPlaying: { autoFit: true, columns: [ diff --git a/src/renderer/themes/default.scss b/src/renderer/themes/default.scss index 5f1ac80e..1acefa0a 100644 --- a/src/renderer/themes/default.scss +++ b/src/renderer/themes/default.scss @@ -48,21 +48,21 @@ --btn-primary-fg: #ffffff; --btn-primary-fg-hover: #ffffff; --btn-primary-border: none; - --btn-primary-radius: 0; + --btn-primary-radius: 4px; --btn-default-bg: rgb(31, 31, 32); --btn-default-bg-hover: rgb(63, 63, 63); --btn-default-fg: rgb(193, 193, 193); --btn-default-fg-hover: rgb(193, 193, 193); --btn-default-border: none; - --btn-default-radius: 0; + --btn-default-radius: 2px; --btn-subtle-bg: transparent; --btn-subtle-bg-hover: transparent; --btn-subtle-fg: rgb(220, 220, 220); --btn-subtle-fg-hover: rgb(255, 255, 255); --btn-subtle-border: none; - --btn-subtle-radius: 0; + --btn-subtle-radius: 4px; --btn-outline-bg: transparent; --btn-outline-bg-hover: transparent; @@ -77,13 +77,13 @@ --input-active-fg: rgb(193, 193, 193); --input-active-bg: rgba(255, 255, 255, 0.1); - --dropdown-menu-bg: rgb(45, 45, 45); + --dropdown-menu-bg: rgb(32, 32, 32); --dropdown-menu-fg: rgb(235, 235, 235); --dropdown-menu-item-padding: 0.8rem; --dropdown-menu-item-font-size: 1rem; --dropdown-menu-bg-hover: rgb(62, 62, 62); --dropdown-menu-border: 1px var(--generic-border-color) solid; - --dropdown-menu-border-radius: 0; + --dropdown-menu-border-radius: 4px; --switch-track-bg: rgb(50, 50, 50); --switch-track-enabled-bg: var(--primary-color); @@ -106,7 +106,7 @@ --paper-bg: rgb(20, 20, 20); - --placeholder-bg: rgba(53, 53, 53, 0.5); + --placeholder-bg: rgba(53, 53, 53, 1); --placeholder-fg: rgba(126, 126, 126); --card-default-bg: rgb(32, 32, 32); diff --git a/src/renderer/themes/light.scss b/src/renderer/themes/light.scss index 1890b2e9..a096291d 100644 --- a/src/renderer/themes/light.scss +++ b/src/renderer/themes/light.scss @@ -52,6 +52,13 @@ body[data-theme='defaultLight'] { --btn-subtle-fg: rgb(80, 80, 80); --btn-subtle-fg-hover: rgb(0, 0, 0); + --btn-outline-bg: transparent; + --btn-outline-bg-hover: transparent; + --btn-outline-fg: rgb(60, 60, 60); + --btn-outline-fg-hover: rgb(0, 0, 0); + --btn-outline-border: 1px rgba(140, 140, 140, 0.5) solid; + --btn-outline-radius: 1px; + --input-bg: rgb(240, 241, 242); --input-fg: rgb(0, 0, 0); --input-placeholder-fg: rgb(119, 126, 139); diff --git a/src/renderer/types.ts b/src/renderer/types.ts index b2941b2d..8fa7deab 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -18,7 +18,7 @@ export type CardRoute = { slugs?: RouteSlug[]; }; -export type TableType = 'nowPlaying' | 'sideQueue' | 'sideDrawerQueue' | 'songs'; +export type TableType = 'nowPlaying' | 'sideQueue' | 'sideDrawerQueue' | 'songs' | 'fullScreen'; export type CardRow = { arrayProperty?: string;