mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-09 20:29:36 +02:00
fix mouseover state causing rerender in fullscreen player (#1535)
This commit is contained in:
@@ -91,7 +91,7 @@ export const FullScreenPlayerQueue = () => {
|
|||||||
pos="relative"
|
pos="relative"
|
||||||
size="lg"
|
size="lg"
|
||||||
uppercase
|
uppercase
|
||||||
variant="subtle"
|
variant="transparent"
|
||||||
>
|
>
|
||||||
{item.label}
|
{item.label}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -10,8 +10,31 @@
|
|||||||
@media screen and (orientation: portrait) {
|
@media screen and (orientation: portrait) {
|
||||||
padding: 2rem 2rem 1rem;
|
padding: 2rem 2rem 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover .controls-container {
|
||||||
|
[data-variant='subtle'] {
|
||||||
|
color: var(--theme-colors-foreground);
|
||||||
|
background: var(--theme-colors-surface);
|
||||||
|
border: 1px solid transparent;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus-visible {
|
||||||
|
@mixin dark {
|
||||||
|
background: lighten(var(--theme-colors-surface), 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin light {
|
||||||
|
background: lighten(var(--theme-colors-surface), 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.responsive-container {
|
.responsive-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: minmax(0, 1fr);
|
grid-template-rows: minmax(0, 1fr);
|
||||||
|
|||||||
@@ -220,11 +220,7 @@ const BackgroundImageOverlay = memo(
|
|||||||
|
|
||||||
BackgroundImageOverlay.displayName = 'BackgroundImageOverlay';
|
BackgroundImageOverlay.displayName = 'BackgroundImageOverlay';
|
||||||
|
|
||||||
interface ControlsProps {
|
const Controls = () => {
|
||||||
isPageHovered: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Controls = ({ isPageHovered }: ControlsProps) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const {
|
const {
|
||||||
dynamicBackground,
|
dynamicBackground,
|
||||||
@@ -271,6 +267,7 @@ const Controls = ({ isPageHovered }: ControlsProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Group
|
<Group
|
||||||
|
className={styles.controlsContainer}
|
||||||
gap="sm"
|
gap="sm"
|
||||||
p="1rem"
|
p="1rem"
|
||||||
pos="absolute"
|
pos="absolute"
|
||||||
@@ -285,7 +282,7 @@ const Controls = ({ isPageHovered }: ControlsProps) => {
|
|||||||
iconProps={{ size: 'lg' }}
|
iconProps={{ size: 'lg' }}
|
||||||
onClick={handleToggleFullScreenPlayer}
|
onClick={handleToggleFullScreenPlayer}
|
||||||
tooltip={{ label: t('common.minimize', { postProcess: 'titleCase' }) }}
|
tooltip={{ label: t('common.minimize', { postProcess: 'titleCase' }) }}
|
||||||
variant={isPageHovered ? 'default' : 'subtle'}
|
variant="subtle"
|
||||||
/>
|
/>
|
||||||
<Popover position="bottom-start">
|
<Popover position="bottom-start">
|
||||||
<Popover.Target>
|
<Popover.Target>
|
||||||
@@ -293,7 +290,7 @@ const Controls = ({ isPageHovered }: ControlsProps) => {
|
|||||||
icon="settings2"
|
icon="settings2"
|
||||||
iconProps={{ size: 'lg' }}
|
iconProps={{ size: 'lg' }}
|
||||||
tooltip={{ label: t('common.configure', { postProcess: 'titleCase' }) }}
|
tooltip={{ label: t('common.configure', { postProcess: 'titleCase' }) }}
|
||||||
variant={isPageHovered ? 'default' : 'subtle'}
|
variant="subtle"
|
||||||
/>
|
/>
|
||||||
</Popover.Target>
|
</Popover.Target>
|
||||||
<Popover.Dropdown>
|
<Popover.Dropdown>
|
||||||
@@ -556,7 +553,7 @@ const Controls = ({ isPageHovered }: ControlsProps) => {
|
|||||||
</Popover>
|
</Popover>
|
||||||
<ListConfigMenu
|
<ListConfigMenu
|
||||||
buttonProps={{
|
buttonProps={{
|
||||||
variant: isPageHovered ? 'default' : 'subtle',
|
variant: 'subtle',
|
||||||
}}
|
}}
|
||||||
displayTypes={[{ hidden: true, value: ListDisplayType.GRID }]}
|
displayTypes={[{ hidden: true, value: ListDisplayType.GRID }]}
|
||||||
listKey={ItemListKey.FULL_SCREEN}
|
listKey={ItemListKey.FULL_SCREEN}
|
||||||
@@ -616,20 +613,11 @@ interface PlayerContainerProps {
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
dynamicBackground: boolean | undefined;
|
dynamicBackground: boolean | undefined;
|
||||||
dynamicIsImage: boolean | undefined;
|
dynamicIsImage: boolean | undefined;
|
||||||
onMouseEnter: () => void;
|
|
||||||
onMouseLeave: () => void;
|
|
||||||
windowBarStyle: Platform;
|
windowBarStyle: Platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlayerContainer = memo(
|
const PlayerContainer = memo(
|
||||||
({
|
({ children, dynamicBackground, dynamicIsImage, windowBarStyle }: PlayerContainerProps) => {
|
||||||
children,
|
|
||||||
dynamicBackground,
|
|
||||||
dynamicIsImage,
|
|
||||||
onMouseEnter,
|
|
||||||
onMouseLeave,
|
|
||||||
windowBarStyle,
|
|
||||||
}: PlayerContainerProps) => {
|
|
||||||
const currentSong = usePlayerSong();
|
const currentSong = usePlayerSong();
|
||||||
const imageUrl = useItemImageUrl({
|
const imageUrl = useItemImageUrl({
|
||||||
id: currentSong?.imageId || undefined,
|
id: currentSong?.imageId || undefined,
|
||||||
@@ -650,8 +638,6 @@ const PlayerContainer = memo(
|
|||||||
custom={{ background, dynamicBackground, windowBarStyle }}
|
custom={{ background, dynamicBackground, windowBarStyle }}
|
||||||
exit="closed"
|
exit="closed"
|
||||||
initial="closed"
|
initial="closed"
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
onMouseLeave={onMouseLeave}
|
|
||||||
transition={{ duration: 2 }}
|
transition={{ duration: 2 }}
|
||||||
variants={containerVariants}
|
variants={containerVariants}
|
||||||
>
|
>
|
||||||
@@ -672,8 +658,6 @@ export const FullScreenPlayer = () => {
|
|||||||
const { setStore } = useFullScreenPlayerStoreActions();
|
const { setStore } = useFullScreenPlayerStoreActions();
|
||||||
const { windowBarStyle } = useWindowSettings();
|
const { windowBarStyle } = useWindowSettings();
|
||||||
|
|
||||||
const [isPageHovered, setIsPageHovered] = useState(false);
|
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const isOpenedRef = useRef<boolean | null>(null);
|
const isOpenedRef = useRef<boolean | null>(null);
|
||||||
|
|
||||||
@@ -689,11 +673,9 @@ export const FullScreenPlayer = () => {
|
|||||||
<PlayerContainer
|
<PlayerContainer
|
||||||
dynamicBackground={dynamicBackground}
|
dynamicBackground={dynamicBackground}
|
||||||
dynamicIsImage={dynamicIsImage}
|
dynamicIsImage={dynamicIsImage}
|
||||||
onMouseEnter={() => setIsPageHovered(true)}
|
|
||||||
onMouseLeave={() => setIsPageHovered(false)}
|
|
||||||
windowBarStyle={windowBarStyle}
|
windowBarStyle={windowBarStyle}
|
||||||
>
|
>
|
||||||
<Controls isPageHovered={isPageHovered} />
|
<Controls />
|
||||||
<BackgroundImageOverlay
|
<BackgroundImageOverlay
|
||||||
dynamicBackground={dynamicBackground}
|
dynamicBackground={dynamicBackground}
|
||||||
dynamicImageBlur={dynamicImageBlur}
|
dynamicImageBlur={dynamicImageBlur}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { memo, ReactNode, useMemo } from 'react';
|
import { ReactNode, useMemo } from 'react';
|
||||||
|
|
||||||
import styles from './option.module.css';
|
import styles from './option.module.css';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ interface OptionProps extends GroupProps {
|
|||||||
|
|
||||||
const defaultClassNames = { root: styles.root };
|
const defaultClassNames = { root: styles.root };
|
||||||
|
|
||||||
export const Option = memo(({ children, classNames, ...props }: OptionProps) => {
|
export const Option = ({ children, classNames, ...props }: OptionProps) => {
|
||||||
const mergedClassNames = useMemo(
|
const mergedClassNames = useMemo(
|
||||||
() => (classNames ? { ...defaultClassNames, ...classNames } : defaultClassNames),
|
() => (classNames ? { ...defaultClassNames, ...classNames } : defaultClassNames),
|
||||||
[classNames],
|
[classNames],
|
||||||
@@ -23,7 +23,7 @@ export const Option = memo(({ children, classNames, ...props }: OptionProps) =>
|
|||||||
{children}
|
{children}
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
});
|
};
|
||||||
|
|
||||||
Option.displayName = 'Option';
|
Option.displayName = 'Option';
|
||||||
|
|
||||||
@@ -43,5 +43,5 @@ const Control = ({ children }: ControlProps) => {
|
|||||||
return <Flex justify="flex-end">{children}</Flex>;
|
return <Flex justify="flex-end">{children}</Flex>;
|
||||||
};
|
};
|
||||||
|
|
||||||
(Option as typeof Option & { Label: typeof Label }).Label = Label;
|
Option.Label = Label;
|
||||||
(Option as typeof Option & { Control: typeof Control }).Control = Control;
|
Option.Control = Control;
|
||||||
|
|||||||
Reference in New Issue
Block a user