Add transparency/opacity for queue sidebar (#231)
* add opacity * add background for song metadata * Add padding and border radius to opacity elements * Remove font-weight transition on active lyrics (#233) --------- Co-authored-by: jeffvli <jeffvictorli@gmail.com>
This commit is contained in:
parent
0ae53b023c
commit
c8397bb5ef
7 changed files with 47 additions and 8 deletions
|
@ -11,13 +11,13 @@ interface LyricLineProps extends ComponentPropsWithoutRef<'div'> {
|
||||||
|
|
||||||
const StyledText = styled(TextTitle)<TitleProps & { $alignment: string; $fontSize: number }>`
|
const StyledText = styled(TextTitle)<TitleProps & { $alignment: string; $fontSize: number }>`
|
||||||
color: var(--main-fg);
|
color: var(--main-fg);
|
||||||
font-weight: 400;
|
font-weight: 600;
|
||||||
text-align: ${(props) => props.$alignment};
|
text-align: ${(props) => props.$alignment};
|
||||||
font-size: ${(props) => props.$fontSize}px;
|
font-size: ${(props) => props.$fontSize}px;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
padding: 0 1rem;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
font-weight: 800;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,15 @@ const ImageContainer = styled(motion.div)`
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const MetadataContainer = styled(Stack)`
|
interface TransparentMetadataContainer {
|
||||||
|
opacity: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MetadataContainer = styled(Stack)<TransparentMetadataContainer>`
|
||||||
|
background: rgba(var(--main-bg-transparent), ${({ opacity }) => opacity}%);
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 3.5vh;
|
font-size: 3.5vh;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +128,7 @@ const ImageWithPlaceholder = ({
|
||||||
|
|
||||||
export const FullScreenPlayerImage = () => {
|
export const FullScreenPlayerImage = () => {
|
||||||
const { queue } = usePlayerData();
|
const { queue } = usePlayerData();
|
||||||
const useImageAspectRatio = useFullScreenPlayerStore((state) => state.useImageAspectRatio);
|
const { opacity, useImageAspectRatio } = useFullScreenPlayerStore();
|
||||||
const currentSong = queue.current;
|
const currentSong = queue.current;
|
||||||
const { color: background } = useFastAverageColor({
|
const { color: background } = useFastAverageColor({
|
||||||
algorithm: 'dominant',
|
algorithm: 'dominant',
|
||||||
|
@ -208,6 +216,7 @@ export const FullScreenPlayerImage = () => {
|
||||||
<MetadataContainer
|
<MetadataContainer
|
||||||
className="full-screen-player-image-metadata"
|
className="full-screen-player-image-metadata"
|
||||||
maw="100%"
|
maw="100%"
|
||||||
|
opacity={opacity}
|
||||||
spacing="xs"
|
spacing="xs"
|
||||||
>
|
>
|
||||||
<TextTitle
|
<TextTitle
|
||||||
|
|
|
@ -41,14 +41,21 @@ const HeaderItemWrapper = styled.div`
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const GridContainer = styled.div`
|
interface TransparendGridContainerProps {
|
||||||
|
opacity: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GridContainer = styled.div<TransparendGridContainerProps>`
|
||||||
|
padding: 1rem;
|
||||||
|
background: rgba(var(--main-bg-transparent), ${({ opacity }) => opacity}%);
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto minmax(0, 1fr);
|
grid-template-rows: auto minmax(0, 1fr);
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
border-radius: 5px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const FullScreenPlayerQueue = () => {
|
export const FullScreenPlayerQueue = () => {
|
||||||
const { activeTab } = useFullScreenPlayerStore();
|
const { activeTab, opacity } = useFullScreenPlayerStore();
|
||||||
const { setStore } = useFullScreenPlayerStoreActions();
|
const { setStore } = useFullScreenPlayerStoreActions();
|
||||||
|
|
||||||
const headerItems = [
|
const headerItems = [
|
||||||
|
@ -73,7 +80,10 @@ export const FullScreenPlayerQueue = () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GridContainer className="full-screen-player-queue-container">
|
<GridContainer
|
||||||
|
className="full-screen-player-queue-container"
|
||||||
|
opacity={opacity}
|
||||||
|
>
|
||||||
<Group
|
<Group
|
||||||
grow
|
grow
|
||||||
align="center"
|
align="center"
|
||||||
|
|
|
@ -70,7 +70,8 @@ const BackgroundImageOverlay = styled.div`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Controls = () => {
|
const Controls = () => {
|
||||||
const { dynamicBackground, expanded, useImageAspectRatio } = useFullScreenPlayerStore();
|
const { dynamicBackground, expanded, opacity, useImageAspectRatio } =
|
||||||
|
useFullScreenPlayerStore();
|
||||||
const { setStore } = useFullScreenPlayerStoreActions();
|
const { setStore } = useFullScreenPlayerStoreActions();
|
||||||
const { setSettings } = useSettingsStoreActions();
|
const { setSettings } = useSettingsStoreActions();
|
||||||
const lyricConfig = useLyricsSettings();
|
const lyricConfig = useLyricsSettings();
|
||||||
|
@ -134,6 +135,21 @@ const Controls = () => {
|
||||||
/>
|
/>
|
||||||
</Option.Control>
|
</Option.Control>
|
||||||
</Option>
|
</Option>
|
||||||
|
{dynamicBackground && (
|
||||||
|
<Option>
|
||||||
|
<Option.Label>Opacity</Option.Label>
|
||||||
|
<Option.Control>
|
||||||
|
<Slider
|
||||||
|
defaultValue={opacity}
|
||||||
|
label={(e) => `${e} %`}
|
||||||
|
max={100}
|
||||||
|
min={1}
|
||||||
|
w="100%"
|
||||||
|
onChangeEnd={(e) => setStore({ opacity: Number(e) })}
|
||||||
|
/>
|
||||||
|
</Option.Control>
|
||||||
|
</Option>
|
||||||
|
)}
|
||||||
<Option>
|
<Option>
|
||||||
<Option.Label>Use image aspect ratio</Option.Label>
|
<Option.Label>Use image aspect ratio</Option.Label>
|
||||||
<Option.Control>
|
<Option.Control>
|
||||||
|
|
|
@ -7,6 +7,7 @@ interface FullScreenPlayerState {
|
||||||
activeTab: string | 'queue' | 'related' | 'lyrics';
|
activeTab: string | 'queue' | 'related' | 'lyrics';
|
||||||
dynamicBackground?: boolean;
|
dynamicBackground?: boolean;
|
||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
|
opacity: number;
|
||||||
useImageAspectRatio: boolean;
|
useImageAspectRatio: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ export const useFullScreenPlayerStore = create<FullScreenPlayerSlice>()(
|
||||||
activeTab: 'queue',
|
activeTab: 'queue',
|
||||||
dynamicBackground: true,
|
dynamicBackground: true,
|
||||||
expanded: false,
|
expanded: false,
|
||||||
|
opacity: 60,
|
||||||
useImageAspectRatio: false,
|
useImageAspectRatio: false,
|
||||||
})),
|
})),
|
||||||
{ name: 'store_full_screen_player' },
|
{ name: 'store_full_screen_player' },
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
--danger-color: rgb(204, 50, 50);
|
--danger-color: rgb(204, 50, 50);
|
||||||
--generic-border-color: rgba(50, 50, 50, 30%);
|
--generic-border-color: rgba(50, 50, 50, 30%);
|
||||||
--main-bg: rgb(18, 18, 18);
|
--main-bg: rgb(18, 18, 18);
|
||||||
|
--main-bg-transparent: 18, 18, 18;
|
||||||
--main-fg: rgb(225, 225, 225);
|
--main-fg: rgb(225, 225, 225);
|
||||||
--main-fg-secondary: rgb(150, 150, 150);
|
--main-fg-secondary: rgb(150, 150, 150);
|
||||||
--window-bar-bg: rgb(16, 16, 16);
|
--window-bar-bg: rgb(16, 16, 16);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
body[data-theme='defaultLight'] {
|
body[data-theme='defaultLight'] {
|
||||||
--icon-color: #fff;
|
--icon-color: #fff;
|
||||||
--main-bg: rgb(255, 255, 255);
|
--main-bg: rgb(255, 255, 255);
|
||||||
|
--main-bg-transparent: 255, 255, 255;
|
||||||
--main-fg: rgb(25, 25, 25);
|
--main-fg: rgb(25, 25, 25);
|
||||||
--main-fg-secondary: rgb(80, 80, 80);
|
--main-fg-secondary: rgb(80, 80, 80);
|
||||||
--titlebar-fg: rgb(25, 25, 25);
|
--titlebar-fg: rgb(25, 25, 25);
|
||||||
|
|
Reference in a new issue