Browse Source

add experimental dynamic background

master
jeffvli 3 years ago
parent
commit
b0c101604f
  1. 1
      src/__tests__/App.test.tsx
  2. 40
      src/components/layout/GenericPage.tsx
  3. 25
      src/components/layout/styled.tsx
  4. 26
      src/components/settings/ConfigPanels/LookAndFeelConfig.tsx
  5. 4
      src/components/shared/setDefaultSettings.ts
  6. 7
      src/redux/miscSlice.ts
  7. 84
      src/shared/settings.json
  8. 9
      src/shared/utils.ts

1
src/__tests__/App.test.tsx

@ -76,6 +76,7 @@ const miscState: General = {
},
modalPages: [],
isProcessingPlaylist: [],
dynamicBackground: false,
};
const mockInitialState = {

40
src/components/layout/GenericPage.tsx

@ -1,10 +1,46 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import path from 'path';
import { Divider } from 'rsuite';
import { useAppSelector } from '../../redux/hooks';
import { PageContainer, PageHeader, PageContent } from './styled';
import { isCached, getImageCachePath } from '../../shared/utils';
const GenericPage = ({ header, children, hideDivider, ...rest }: any) => {
const playQueue = useAppSelector((state) => state.playQueue);
const misc = useAppSelector((state) => state.misc);
const [cachePath] = useState(path.join(getImageCachePath(), '/'));
const [backgroundImage, setBackgroundImage] = useState('');
useEffect(() => {
if (misc.dynamicBackground) {
const cachedImagePath = `${cachePath}album_${playQueue.current?.albumId}.jpg`;
const serverImagePath = playQueue.current?.image.replace(
/size=\d+/,
'size=500'
);
const cssBackgroundImagePath = `${cachePath}album_${playQueue.current?.albumId}.jpg`.replaceAll(
'\\',
'/'
);
if (!isCached(cachedImagePath)) {
const preloadImage = new Image();
preloadImage.src = serverImagePath;
}
const imagePath = isCached(cachedImagePath)
? cssBackgroundImagePath
: serverImagePath;
setBackgroundImage(imagePath);
}
}, [cachePath, misc.dynamicBackground, playQueue]);
return (
<PageContainer id="page-container">
<PageContainer
id="page-container"
$backgroundSrc={misc.dynamicBackground ? backgroundImage : undefined}
>
<PageHeader
id="page-header"
padding={rest.padding}

25
src/components/layout/styled.tsx

@ -40,6 +40,7 @@ export const RootFooter = styled(Footer)`
// Titlebar.tsx
// Subtract 2px from width if you add window border
export const TitleHeader = styled.header<{ font: string }>`
z-index: 1;
display: block;
position: fixed;
height: 32px;
@ -98,13 +99,35 @@ export const WindowControlButton = styled.div<{
`;
// GenericPage.tsx
export const PageContainer = styled(Container)`
export const PageContainer = styled(Container)<{ $backgroundSrc?: string }>`
height: 100%;
overflow-x: hidden;
&:before {
content: '';
position: fixed;
left: 0;
right: 0;
display: block;
background-image: ${(props) =>
props.$backgroundSrc ? `url(${props.$backgroundSrc})` : undefined};
transition: background-image 1s ease-in-out;
width: 100%;
height: 92%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
opacity: 0.3;
filter: blur(50px) brightness(0.8);
}
`;
export const PageHeader = styled(Header)<{ padding?: string }>`
padding: ${(props) => (props.padding ? props.padding : '10px 20px 0px 20px')};
z-index: 1;
`;
export const PageContent = styled(Content)<{ padding?: string }>`

26
src/components/settings/ConfigPanels/LookAndFeelConfig.tsx

@ -7,11 +7,16 @@ import {
StyledInputPicker,
StyledNavItem,
StyledInputNumber,
StyledCheckbox,
} from '../../shared/styled';
import ListViewConfig from './ListViewConfig';
import { Fonts } from '../Fonts';
import { useAppDispatch } from '../../../redux/hooks';
import { setTheme, setFont } from '../../../redux/miscSlice';
import {
setTheme,
setFont,
setDynamicBackground,
} from '../../../redux/miscSlice';
import {
songColumnPicker,
songColumnList,
@ -53,7 +58,26 @@ const LookAndFeelConfig = () => {
<StyledRadio value="defaultLight">Default Light</StyledRadio>
</RadioGroup>
<br />
<StyledCheckbox
defaultChecked={settings.getSync('dynamicBackground')}
onChange={() => {
settings.setSync(
'dynamicBackground',
!settings.getSync('dynamicBackground')
);
dispatch(
setDynamicBackground(
Boolean(settings.getSync('dynamicBackground'))
)
);
}}
>
Enable dynamic background
</StyledCheckbox>
<br />
<ControlLabel>Font</ControlLabel>
<br />
<StyledInputPicker
data={Fonts}

4
src/components/shared/setDefaultSettings.ts

@ -12,6 +12,10 @@ const setDefaultSettings = (force: boolean) => {
settings.setSync('font', 'Poppins');
}
if (force || !settings.hasSync('dynamicBackground')) {
settings.setSync('dynamicBackground', false);
}
if (force || !settings.hasSync('showDebugWindow')) {
settings.setSync('showDebugWindow', false);
}

7
src/redux/miscSlice.ts

@ -28,6 +28,7 @@ export interface General {
expandSidebar: boolean;
isProcessingPlaylist: string[];
contextMenu: ContextMenu;
dynamicBackground: boolean;
}
const initialState: General = {
@ -43,12 +44,17 @@ const initialState: General = {
contextMenu: {
show: false,
},
dynamicBackground: parsedSettings.dynamicBackground,
};
const miscSlice = createSlice({
name: 'misc',
initialState,
reducers: {
setDynamicBackground: (state, action: PayloadAction<boolean>) => {
state.dynamicBackground = action.payload;
},
setExpandSidebar: (state, action: PayloadAction<boolean>) => {
state.expandSidebar = action.payload;
},
@ -139,5 +145,6 @@ export const {
removeProcessingPlaylist,
setContextMenu,
setExpandSidebar,
setDynamicBackground,
} = miscSlice.actions;
export default miscSlice.reducer;

84
src/shared/settings.json

@ -1,30 +1,40 @@
{
"theme": "defaultDark",
"showDebugWindow": false,
"globalMediaHotkeys": true,
"cachePath": "C:\\Users\\jli\\AppData\\Roaming\\Electron",
"volume": 0.93,
"seekForwardInterval": 5,
"seekBackwardInterval": 5,
"volumeFade": true,
"repeat": "all",
"shuffle": false,
"scrollWithCurrentSong": true,
"cacheImages": true,
"cacheSongs": false,
"fadeDuration": "9.0",
"playlistViewType": "list",
"albumViewType": "list",
"songListFontSize": "14",
"songListRowHeight": "60.0",
"songListColumns": [
"pollingInterval": 20,
"fadeDuration": 9,
"fadeType": "equalPower",
"gridCardSize": 200,
"playlistViewType": "grid",
"albumViewType": "grid",
"musicListFontSize": "13",
"musicListRowHeight": "50",
"musicListColumns": [
{
"id": "#",
"dataKey": "index",
"alignment": "center",
"resizable": true,
"width": 50,
"label": "#"
"label": "# (Drag/Drop)"
},
{
"id": "Title",
"dataKey": "combinedtitle",
"alignment": "left",
"resizable": true,
"width": 450,
"width": 273,
"label": "Title (Combined)"
},
{
@ -32,7 +42,7 @@
"dataKey": "album",
"alignment": "left",
"resizable": true,
"width": 450,
"width": 263,
"label": "Album"
},
{
@ -40,20 +50,28 @@
"dataKey": "duration",
"alignment": "center",
"resizable": true,
"width": 100,
"width": 110,
"label": "Duration"
},
{
"id": "Bitrate",
"dataKey": "bitRate",
"alignment": "left",
"resizable": true,
"width": 72,
"label": "Bitrate"
},
{
"id": "Fav",
"dataKey": "starred",
"alignment": "center",
"resizable": true,
"width": 60,
"width": 100,
"label": "Favorite"
}
],
"albumListFontSize": "14",
"albumListRowHeight": "60.0",
"albumListRowHeight": "60",
"albumListColumns": [
{
"id": "#",
@ -68,7 +86,7 @@
"dataKey": "combinedtitle",
"alignment": "left",
"resizable": true,
"width": 450,
"width": 457,
"label": "Title (Combined)"
},
{
@ -84,7 +102,7 @@
"dataKey": "duration",
"alignment": "center",
"resizable": true,
"width": 100,
"width": 80,
"label": "Duration"
},
{
@ -92,12 +110,12 @@
"dataKey": "starred",
"alignment": "center",
"resizable": true,
"width": 60,
"width": 100,
"label": "Favorite"
}
],
"playlistListFontSize": "14",
"playlistListRowHeight": "55.0",
"playlistListRowHeight": "80",
"playlistListColumns": [
{
"id": "#",
@ -156,6 +174,36 @@
"label": "Modified"
}
],
"defaultRepeat": "all",
"defaultShuffle": true
"miniListFontSize": "14",
"miniListColumns": [
{
"id": "#",
"dataKey": "index",
"alignment": "center",
"resizable": true,
"width": 50,
"label": "# (Drag/Drop)"
},
{
"id": "Title",
"dataKey": "title",
"alignment": "left",
"resizable": true,
"width": 250,
"label": "Title"
},
{
"id": "Duration",
"dataKey": "duration",
"alignment": "center",
"resizable": true,
"width": 80,
"label": "Duration"
}
],
"font": "Poppins",
"server": "http://192.168.14.11:4040",
"serverBase64": "aHR0cDovLzE5Mi4xNjguMTQuMTE6NDA0MA==",
"miniListRowHeight": "30",
"dynamicBackground": false
}

9
src/shared/utils.ts

@ -1,6 +1,5 @@
import fs from 'fs';
import path from 'path';
import settings from 'electron-settings';
import moment from 'moment';
let settingsPath = path.join(
@ -28,6 +27,9 @@ export const getSettings = () => {
theme: parsedSettings.theme,
font: parsedSettings.font,
scrollWithCurrentSong: parsedSettings.scrollWithCurrentSong,
dynamicBackground: parsedSettings.dynamicBackground,
cachePath: parsedSettings.cachePath,
serverBase64: parsedSettings.serverBase64,
};
};
@ -36,10 +38,11 @@ export const isCached = (filePath: string) => {
};
export const getRootCachePath = () => {
const parsedSettings = getSettings();
return path.join(
String(settings.getSync('cachePath')),
parsedSettings.cachePath,
'sonixdCache',
`${settings.getSync('serverBase64')}`
parsedSettings.serverBase64
);
};

Loading…
Cancel
Save