Skip to content

Commit

Permalink
Album blur, allow clicking the playerbar to toggle the player, misc c…
Browse files Browse the repository at this point in the history
…hanges (#717)

* Album blur, allow clicking the playerbar to toggle the player

* Fix stopProporagion, sync package with upsteam, update translation

* recommit my existing changes

* Update default albumBackgroundBlur to 6

* according to git this commit resets the package files

* merge with our fork because pyx forgot to add it

* try adding a setting

* change the playerbar animation

* make the animation quicker bc its choppy

* change playerbar to use a bool instead

* requested opacity fix

* Refactor classes to use clsx

---------

Co-authored-by: iiPython <ben@iipython.dev>
Co-authored-by: Jeff <42182408+jeffvli@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 1, 2024
1 parent b93ad40 commit eb50c69
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 29 deletions.
6 changes: 6 additions & 0 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@
"setting": {
"accentColor": "accent color",
"accentColor_description": "sets the accent color for the application",
"albumBackground": "album background image",
"albumBackground_description": "adds a background image for album pages containing the album art",
"albumBackgroundBlur": "album background image blur size",
"albumBackgroundBlur_description": "adjusts the amount of blur applied to the album background image",
"applicationHotkeys": "application hotkeys",
"applicationHotkeys_description": "configure application hotkeys. toggle the checkbox to set as a global hotkey (desktop only)",
"audioDevice": "audio device",
Expand Down Expand Up @@ -587,6 +591,8 @@
"playButtonBehavior_optionPlay": "$t(player.play)",
"playerAlbumArtResolution": "player album art resolution",
"playerAlbumArtResolution_description": "the resolution for the large player's album art preview. larger makes it look more crisp, but may slow loading down. defaults to 0, meaning auto",
"playerbarOpenDrawer": "playerbar fullscreen toggle",
"playerbarOpenDrawer_description": "allows clicking of the playerbar to open the full screen player",
"remotePassword": "remote control server password",
"remotePassword_description": "sets the password for the remote control server. These credentials are by default transferred insecurely, so you should use a unique password that you do not care about",
"remotePort": "remote control server port",
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@
},
"albumArtistDetail": {
"viewAllTracks": "ver todo de $t(entity.track_other)",
"relatedArtists": "similar a $t(entity.artist_other)",
"relatedArtists": "$t(entity.artist_other) similar",
"topSongs": "mejores canciones",
"topSongsFrom": "las mejores canciones de {{title}}",
"viewAll": "Ver todo",
Expand Down
11 changes: 7 additions & 4 deletions src/renderer/features/albums/components/album-detail-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import { useCurrentServer } from '/@/renderer/store';
import { formatDateAbsolute, formatDurationString } from '/@/renderer/utils';

interface AlbumDetailHeaderProps {
background: string;
background: {
background: string;
blur: number;
};
}

export const AlbumDetailHeader = forwardRef(
Expand All @@ -24,6 +27,8 @@ export const AlbumDetailHeader = forwardRef(
const cq = useContainerQuery();
const { t } = useTranslation();

const showRating = detailQuery?.data?.serverType === ServerType.NAVIDROME;

const originalDifferentFromRelease =
detailQuery.data?.originalDate &&
detailQuery.data.originalDate !== detailQuery.data.releaseDate;
Expand Down Expand Up @@ -78,16 +83,14 @@ export const AlbumDetailHeader = forwardRef(
});
};

const showRating = detailQuery?.data?.serverType === ServerType.NAVIDROME;

return (
<Stack ref={cq.ref}>
<LibraryHeader
ref={ref}
background={background}
imageUrl={detailQuery?.data?.imageUrl}
item={{ route: AppRoute.LIBRARY_ALBUMS, type: LibraryItem.ALBUM }}
title={detailQuery?.data?.name || ''}
{...background}
>
<Stack spacing="sm">
<Group spacing="sm">
Expand Down
17 changes: 12 additions & 5 deletions src/renderer/features/albums/routes/album-detail-route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ import { AlbumDetailHeader } from '/@/renderer/features/albums/components/album-
import { usePlayQueueAdd } from '/@/renderer/features/player';
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
import { LibraryItem } from '/@/renderer/api/types';
import { useCurrentServer } from '/@/renderer/store';
import { useCurrentServer, useGeneralSettings } from '/@/renderer/store';

const AlbumDetailRoute = () => {
const tableRef = useRef<AgGridReactType | null>(null);
const scrollAreaRef = useRef<HTMLDivElement>(null);
const headerRef = useRef<HTMLDivElement>(null);
const { albumBackground, albumBackgroundBlur } = useGeneralSettings();

const { albumId } = useParams() as { albumId: string };
const server = useCurrentServer();
const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id });
const { color: background, colorId } = useFastAverageColor({
const { color: backgroundColor, colorId } = useFastAverageColor({
id: albumId,
src: detailQuery.data?.imageUrl,
srcLoaded: !detailQuery.isLoading,
Expand All @@ -38,16 +39,19 @@ const AlbumDetailRoute = () => {
});
};

if (!background || colorId !== albumId) {
if (!backgroundColor || colorId !== albumId) {
return <Spinner container />;
}

const backgroundUrl = detailQuery.data?.imageUrl || '';
const background = (albumBackground && `url(${backgroundUrl})`) || backgroundColor;

return (
<AnimatedPage key={`album-detail-${albumId}`}>
<NativeScrollArea
ref={scrollAreaRef}
pageHeaderProps={{
backgroundColor: background,
backgroundColor: backgroundColor || undefined,
children: (
<LibraryHeaderBar>
<LibraryHeaderBar.PlayButton onClick={handlePlay} />
Expand All @@ -62,7 +66,10 @@ const AlbumDetailRoute = () => {
>
<AlbumDetailHeader
ref={headerRef}
background={background}
background={{
background,
blur: (albumBackground && albumBackgroundBlur) || 0,
}}
/>
<AlbumDetailContent
background={background}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { forwardRef, Fragment, Ref } from 'react';
import { Group, Rating, Stack } from '@mantine/core';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router';
import { LibraryItem, ServerType } from '/@/renderer/api/types';
import { Text } from '/@/renderer/components';
Expand All @@ -17,6 +18,7 @@ export const AlbumArtistDetailHeader = forwardRef(
({ background }: AlbumArtistDetailHeaderProps, ref: Ref<HTMLDivElement>) => {
const { albumArtistId } = useParams() as { albumArtistId: string };
const server = useCurrentServer();
const { t } = useTranslation();
const detailQuery = useAlbumArtistDetail({
query: { id: albumArtistId },
serverId: server?.id,
Expand All @@ -26,12 +28,12 @@ export const AlbumArtistDetailHeader = forwardRef(
{
id: 'albumCount',
secondary: false,
value: detailQuery?.data?.albumCount && `${detailQuery?.data?.albumCount} albums`,
value: t('entity.albumWithCount', { count: detailQuery?.data?.albumCount || 0 }),
},
{
id: 'songCount',
secondary: false,
value: detailQuery?.data?.songCount && `${detailQuery?.data?.songCount} songs`,
value: t('entity.trackWithCount', { count: detailQuery?.data?.songCount || 0 }),
},
{
id: 'duration',
Expand Down
16 changes: 12 additions & 4 deletions src/renderer/features/player/components/left-controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const PlayerbarImage = styled.img`

const LineItem = styled.div<{ $secondary?: boolean }>`
display: inline-block;
width: 95%;
width: fit-content;
max-width: 20vw;
overflow: hidden;
line-height: 1.3;
Expand Down Expand Up @@ -122,6 +122,8 @@ export const LeftControls = () => {
setSideBar({ image: true });
};

const stopPropagation = (e?: MouseEvent) => e?.stopPropagation();

useHotkeys([
[
bindings.toggleFullscreenPlayer.allowGlobal
Expand Down Expand Up @@ -207,7 +209,7 @@ export const LeftControls = () => {
)}
</AnimatePresence>
<MetadataStack layout="position">
<LineItem>
<LineItem onClick={stopPropagation}>
<Group
noWrap
align="flex-start"
Expand All @@ -234,7 +236,10 @@ export const LeftControls = () => {
)}
</Group>
</LineItem>
<LineItem $secondary>
<LineItem
$secondary
onClick={stopPropagation}
>
{artists?.map((artist, index) => (
<React.Fragment key={`bar-${artist.id}`}>
{index > 0 && <Separator />}
Expand All @@ -257,7 +262,10 @@ export const LeftControls = () => {
</React.Fragment>
))}
</LineItem>
<LineItem $secondary>
<LineItem
$secondary
onClick={stopPropagation}
>
<Text
$link
component={Link}
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/features/player/components/player-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ export const PlayerButton = forwardRef<HTMLDivElement, PlayerButtonProps>(
<StyledPlayerButton
variant={variant}
{...rest}
onClick={(e) => {
e.stopPropagation();
rest.onClick?.(e);
}}
>
{icon}
</StyledPlayerButton>
Expand All @@ -148,6 +152,10 @@ export const PlayerButton = forwardRef<HTMLDivElement, PlayerButtonProps>(
<StyledPlayerButton
variant={variant}
{...rest}
onClick={(e) => {
e.stopPropagation();
rest.onClick?.(e);
}}
>
{icon}
</StyledPlayerButton>
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/features/player/components/playerbar-slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export const PlayerbarSlider = ({ ...props }: SliderProps) => {
},
}}
{...props}
onClick={(e) => {
e?.stopPropagation();
}}
/>
);
};
22 changes: 19 additions & 3 deletions src/renderer/features/player/components/playerbar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { useCallback } from 'react';
import { useCallback, MouseEvent } from 'react';
import styled from 'styled-components';
import { usePlaybackType, useSettingsStore } from '/@/renderer/store/settings.store';
import {
usePlaybackType,
useSettingsStore,
useGeneralSettings,
} from '/@/renderer/store/settings.store';
import { PlaybackType } from '/@/renderer/types';
import { AudioPlayer } from '/@/renderer/components';
import {
Expand All @@ -11,6 +15,8 @@ import {
usePlayer2Data,
usePlayerControls,
useVolume,
useSetFullScreenPlayerStore,
useFullScreenPlayerStore,
} from '/@/renderer/store';
import { CenterControls } from './center-controls';
import { LeftControls } from './left-controls';
Expand Down Expand Up @@ -62,6 +68,7 @@ const CenterGridItem = styled.div`
export const Playerbar = () => {
const playersRef = PlayersRef;
const settings = useSettingsStore((state) => state.playback);
const { playerbarOpenDrawer } = useGeneralSettings();
const playbackType = usePlaybackType();
const volume = useVolume();
const player1 = usePlayer1Data();
Expand All @@ -70,14 +77,23 @@ export const Playerbar = () => {
const player = useCurrentPlayer();
const muted = useMuted();
const { autoNext } = usePlayerControls();
const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore();
const setFullScreenPlayerStore = useSetFullScreenPlayerStore();

const handleToggleFullScreenPlayer = (e?: MouseEvent<HTMLDivElement> | KeyboardEvent) => {
e?.stopPropagation();
setFullScreenPlayerStore({ expanded: !isFullScreenPlayerExpanded });
};

const autoNextFn = useCallback(() => {
const playerData = autoNext();
updateSong(playerData.current.song);
}, [autoNext]);

return (
<PlayerbarContainer>
<PlayerbarContainer
onClick={playerbarOpenDrawer ? handleToggleFullScreenPlayer : undefined}
>
<PlayerbarControlsGrid>
<LeftGridItem>
<LeftControls />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,76 @@ export const ControlSettings = () => {
isHidden: false,
title: t('setting.homeFeature', { postProcess: 'sentenceCase' }),
},
{
control: (
<Switch
aria-label={t('setting.albumBackground', { postProcess: 'sentenceCase' })}
defaultChecked={settings.albumBackground}
onChange={(e) =>
setSettings({
general: {
...settings,
albumBackground: e.currentTarget.checked,
},
})
}
/>
),
description: t('setting.albumBackground', {
context: 'description',
postProcess: 'sentenceCase',
}),
isHidden: false,
title: t('setting.albumBackground', { postProcess: 'sentenceCase' }),
},
{
control: (
<Slider
defaultValue={settings.albumBackgroundBlur}
label={(e) => `${e} rem`}
max={6}
min={0}
step={0.5}
w={100}
onChangeEnd={(e) => {
setSettings({
general: {
...settings,
albumBackgroundBlur: e,
},
});
}}
/>
),
description: t('setting.albumBackgroundBlur', {
context: 'description',
postProcess: 'sentenceCase',
}),
isHidden: false,
title: t('setting.albumBackgroundBlur', { postProcess: 'sentenceCase' }),
},
{
control: (
<Switch
aria-label={t('setting.playerbarOpenDrawer ', { postProcess: 'sentenceCase' })}
defaultChecked={settings.playerbarOpenDrawer}
onChange={(e) =>
setSettings({
general: {
...settings,
playerbarOpenDrawer: e.currentTarget.checked,
},
})
}
/>
),
description: t('setting.playerbarOpenDrawer', {
context: 'description',
postProcess: 'sentenceCase',
}),
isHidden: false,
title: t('setting.playerbarOpenDrawer', { postProcess: 'sentenceCase' }),
},
];

return <SettingsSection options={controlOptions} />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@
width: 100%;
height: 100%;
opacity: 0.9;
background-size: cover !important;
background-position: center !important;
}

.background-overlay {
Expand All @@ -135,6 +137,10 @@
background: var(--bg-header-overlay);
}

.opaque-overlay {
opacity: 0.5;
}

.title {
display: -webkit-box;
overflow: hidden;
Expand Down
Loading

0 comments on commit eb50c69

Please sign in to comment.