throttle volume slider

This commit is contained in:
jeffvli
2026-01-01 15:32:20 -08:00
parent cb47883328
commit c7809c62ce
2 changed files with 25 additions and 10 deletions
@@ -1,5 +1,5 @@
import { t } from 'i18next'; import { t } from 'i18next';
import { useCallback, WheelEvent } from 'react'; import { useCallback, useEffect, useState, WheelEvent } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { PopoverPlayQueue } from '/@/renderer/features/now-playing/components/popover-play-queue'; import { PopoverPlayQueue } from '/@/renderer/features/now-playing/components/popover-play-queue';
@@ -34,6 +34,7 @@ import { Rating } from '/@/shared/components/rating/rating';
import { useHotkeys } from '/@/shared/hooks/use-hotkeys'; import { useHotkeys } from '/@/shared/hooks/use-hotkeys';
import { useMediaQuery } from '/@/shared/hooks/use-media-query'; import { useMediaQuery } from '/@/shared/hooks/use-media-query';
import { useThrottledCallback } from '/@/shared/hooks/use-throttled-callback'; import { useThrottledCallback } from '/@/shared/hooks/use-throttled-callback';
import { useThrottledValue } from '/@/shared/hooks/use-throttled-value';
import { LibraryItem, QueueSong, ServerType } from '/@/shared/types/domain-types'; import { LibraryItem, QueueSong, ServerType } from '/@/shared/types/domain-types';
const calculateVolumeUp = (volume: number, volumeWheelStep: number) => { const calculateVolumeUp = (volume: number, volumeWheelStep: number) => {
@@ -359,6 +360,20 @@ const VolumeButton = () => {
const { mediaToggleMute, setVolume } = usePlayer(); const { mediaToggleMute, setVolume } = usePlayer();
const isMinWidth = useMediaQuery('(max-width: 480px)'); const isMinWidth = useMediaQuery('(max-width: 480px)');
const [sliderValue, setSliderValue] = useState(volume);
const throttledVolume = useThrottledValue(sliderValue, 100);
// Sync throttled value to actual volume
useEffect(() => {
setVolume(throttledVolume);
}, [throttledVolume, setVolume]);
// Sync external volume changes to local state
useEffect(() => {
setSliderValue(volume);
}, [volume]);
const handleVolumeDown = useCallback(() => { const handleVolumeDown = useCallback(() => {
setVolume(Math.max(0, volume - 1)); setVolume(Math.max(0, volume - 1));
}, [setVolume, volume]); }, [setVolume, volume]);
@@ -367,12 +382,9 @@ const VolumeButton = () => {
setVolume(Math.min(100, volume + 1)); setVolume(Math.min(100, volume + 1));
}, [setVolume, volume]); }, [setVolume, volume]);
const handleVolumeSlider = useCallback( const handleVolumeSlider = useCallback((e: number) => {
(e: number) => { setSliderValue(e);
setVolume(e); }, []);
},
[setVolume],
);
const handleMute = useCallback(() => { const handleMute = useCallback(() => {
mediaToggleMute(); mediaToggleMute();
@@ -392,8 +404,8 @@ const VolumeButton = () => {
[setVolume, volume, volumeWheelStep], [setVolume, volume, volumeWheelStep],
); );
const handleVolumeDownThrottled = useThrottledCallback(handleVolumeDown, 50); const handleVolumeDownThrottled = useThrottledCallback(handleVolumeDown, 100);
const handleVolumeUpThrottled = useThrottledCallback(handleVolumeUp, 50); const handleVolumeUpThrottled = useThrottledCallback(handleVolumeUp, 100);
useHotkeys([ useHotkeys([
[bindings.volumeDown.isGlobal ? '' : bindings.volumeDown.hotkey, handleVolumeDownThrottled], [bindings.volumeDown.isGlobal ? '' : bindings.volumeDown.hotkey, handleVolumeDownThrottled],
@@ -428,7 +440,7 @@ const VolumeButton = () => {
onChange={handleVolumeSlider} onChange={handleVolumeSlider}
onWheel={handleVolumeWheel} onWheel={handleVolumeWheel}
size={6} size={6}
value={volume} value={sliderValue}
w={volumeWidth} w={volumeWidth}
/> />
) : null} ) : null}
+3
View File
@@ -0,0 +1,3 @@
import { useThrottledValue as useMantineThrottledValue } from '@mantine/hooks';
export const useThrottledValue = useMantineThrottledValue;