mirror of
https://github.com/FluxaMedia/fluxa-desktop.git
synced 2026-08-19 05:25:49 +00:00
feat: move Stable Volume toggle into in-player settings menu instead of app Settings
This commit is contained in:
parent
53b8fe196c
commit
abbc8e43c8
5 changed files with 31 additions and 18 deletions
|
|
@ -237,6 +237,13 @@ export function ReactPlayerOverlay({ closePlayer, onFirstFrame, initialTitle, in
|
|||
|
||||
const { anime4kEnabled, toggleAnime4k, cycleAnime4kMode } = usePlayerAnime4k({ prefs, persistPreference: setSubtitlePref, flashFeedback });
|
||||
|
||||
const [stableVolumeEnabled, setStableVolumeEnabled] = useState(() => prefs?.stableVolume === true);
|
||||
const toggleStableVolume = useCallback((enabled: boolean) => {
|
||||
sendCmd(`set af ${enabled ? 'dynaudnorm' : '""'}`);
|
||||
setStableVolumeEnabled(enabled);
|
||||
setSubtitlePref('stableVolume', enabled);
|
||||
}, [setSubtitlePref]);
|
||||
|
||||
const subtitleControls = usePlayerSubtitleControls({ prefs, persistPreference: setSubtitlePref, flashFeedback });
|
||||
useEffect(() => { cycleAnime4kModeRef.current = cycleAnime4kMode; }, [cycleAnime4kMode]);
|
||||
|
||||
|
|
@ -324,7 +331,7 @@ export function ReactPlayerOverlay({ closePlayer, onFirstFrame, initialTitle, in
|
|||
cast={castPopoverOpen ? { devices: castDevices, discovering: castDiscovering, activeDeviceId: activeCastDeviceId, anchorRef: castBtnRef, onClose: () => setCastPopoverOpen(false), onSelectDevice: (device) => void selectCastDevice(device), onDisconnect: disconnectCast } : undefined}
|
||||
torrent={showTorrentPopover ? { stats: torrentStatsSnap, anchorRef: torrentBtnRef, onClose: () => setShowTorrentPopover(false) } : undefined}
|
||||
marker={showSegmentMarker && ((introDbSubmitEnabled && introDbApiKey) || (skipDbSubmitEnabled && skipDbApiKey) || (theIntroDbSubmitEnabled && theIntroDbApiKey)) ? { onClose: () => setShowSegmentMarker(false), getPosMs: () => posRef.current * 1000, imdbId: introDbImdbId, tmdbId: introDbTmdbId, mediaType: metaRef?.current?.type === 'series' ? 'tv' : 'movie', season: currentEpisode?.season ?? null, episode: currentEpisode?.episode ?? currentEpisode?.number ?? null, introDbApiKey: introDbSubmitEnabled ? introDbApiKey : '', skipDbApiKey: skipDbSubmitEnabled ? skipDbApiKey : '', theIntroDbApiKey: theIntroDbSubmitEnabled ? theIntroDbApiKey : '', coverage: skipSegmentCoverage ?? {} } : undefined}
|
||||
settings={showPlayerSettings ? { anchorRef: playerSettingsBtnRef, onClose: () => setShowPlayerSettings(false), anime4kEnabled, onToggleAnime4k: toggleAnime4k } : undefined}
|
||||
settings={showPlayerSettings ? { anchorRef: playerSettingsBtnRef, onClose: () => setShowPlayerSettings(false), anime4kEnabled, onToggleAnime4k: toggleAnime4k, stableVolumeEnabled, onToggleStableVolume: toggleStableVolume } : undefined}
|
||||
shortcuts={showShortcutsHelp ? { overrides: shortcutOverrides, onClose: () => setShowShortcutsHelp(false) } : undefined}
|
||||
stats={showStats ? { stats: statsSnap, torrentStats: torrentStatsSnap, bufferHistory: bufferHistoryRef.current, networkSpeedHistory: netSpeedHistoryRef.current, torrentSpeedHistory, stallCount: stallCountRef.current } : undefined}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -7,25 +7,34 @@ interface PlayerSettingsPopoverProps {
|
|||
onClose: () => void;
|
||||
anime4kEnabled: boolean;
|
||||
onToggleAnime4k: (enabled: boolean) => void;
|
||||
stableVolumeEnabled: boolean;
|
||||
onToggleStableVolume: (enabled: boolean) => void;
|
||||
}
|
||||
|
||||
export function PlayerSettingsPopover({ anchorRef, onClose, anime4kEnabled, onToggleAnime4k }: PlayerSettingsPopoverProps) {
|
||||
function SettingsToggleRow({ label, checked, onToggle }: { label: string; checked: boolean; onToggle: () => void }) {
|
||||
return (
|
||||
<div
|
||||
onClick={onToggle}
|
||||
style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '0.75rem', padding: '0.5rem 0.875rem', cursor: 'pointer' }}
|
||||
>
|
||||
<span style={{ color: '#fff', fontSize: '0.8125rem' }}>{label}</span>
|
||||
<div
|
||||
style={{ flexShrink: 0, width: '2.75rem', height: '1.625rem', borderRadius: '62.4375rem', background: checked ? 'var(--primary-accent-color)' : 'rgba(255,255,255,0.14)', position: 'relative', transition: 'background 0.18s' }}
|
||||
>
|
||||
<div style={{ position: 'absolute', top: '0.1875rem', left: checked ? 21 : 3, width: '1.25rem', height: '1.25rem', borderRadius: '50%', background: checked ? '#000000' : 'rgba(255,255,255,0.80)', transition: 'left 0.18s' }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function PlayerSettingsPopover({ anchorRef, onClose, anime4kEnabled, onToggleAnime4k, stableVolumeEnabled, onToggleStableVolume }: PlayerSettingsPopoverProps) {
|
||||
return (
|
||||
<Popover open onClose={onClose} anchorRef={anchorRef} placement="top" width="15rem">
|
||||
<div style={{ color: 'rgba(255,255,255,0.45)', fontSize: '0.6875rem', fontWeight: 700, letterSpacing: '0.05rem', padding: '0.25rem 0.875rem 0.5rem', textTransform: 'uppercase' }}>
|
||||
{t('player.settings')}
|
||||
</div>
|
||||
<div
|
||||
onClick={() => onToggleAnime4k(!anime4kEnabled)}
|
||||
style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '0.75rem', padding: '0.5rem 0.875rem', cursor: 'pointer' }}
|
||||
>
|
||||
<span style={{ color: '#fff', fontSize: '0.8125rem' }}>{t('player.anime4k')}</span>
|
||||
<div
|
||||
style={{ flexShrink: 0, width: '2.75rem', height: '1.625rem', borderRadius: '62.4375rem', background: anime4kEnabled ? 'var(--primary-accent-color)' : 'rgba(255,255,255,0.14)', position: 'relative', transition: 'background 0.18s' }}
|
||||
>
|
||||
<div style={{ position: 'absolute', top: '0.1875rem', left: anime4kEnabled ? 21 : 3, width: '1.25rem', height: '1.25rem', borderRadius: '50%', background: anime4kEnabled ? '#000000' : 'rgba(255,255,255,0.80)', transition: 'left 0.18s' }} />
|
||||
</div>
|
||||
</div>
|
||||
<SettingsToggleRow label={t('player.anime4k')} checked={anime4kEnabled} onToggle={() => onToggleAnime4k(!anime4kEnabled)} />
|
||||
<SettingsToggleRow label={t('player.stable_volume')} checked={stableVolumeEnabled} onToggle={() => onToggleStableVolume(!stableVolumeEnabled)} />
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,7 +155,6 @@ export function PlaybackSection({ prefs, setPref }: { prefs: Prefs; setPref: <K
|
|||
void invoke('player_set_seek_thumbnail_enabled', { enabled: v });
|
||||
}}
|
||||
/>
|
||||
<ToggleTile title={t('settings.stable_volume')} subtitle={t('settings.stable_volume_desc')} checked={prefs.stableVolume} onToggle={(v) => setPref('stableVolume', v)} />
|
||||
<ToggleTile
|
||||
title="HDR output"
|
||||
subtitle="Use HDR output when the display and renderer support it. Falls back to SDR when unavailable."
|
||||
|
|
|
|||
|
|
@ -696,8 +696,6 @@
|
|||
"settings.playback_speed_desc": "Sets the normal playback speed for videos.",
|
||||
"settings.resume_playback_desc": "Continues from the last saved position when you reopen a title.",
|
||||
"settings.forward_rewind_desc": "Sets how far the seek buttons jump forward or back.",
|
||||
"settings.stable_volume": "Stable Volume",
|
||||
"settings.stable_volume_desc": "Evens out loud and quiet moments so volume stays consistent.",
|
||||
"settings.hold_to_speed": "Hold to Speed",
|
||||
"settings.hold_to_speed_desc": "Temporarily speeds up playback while you hold the video.",
|
||||
"settings.hold_speed": "Hold Speed",
|
||||
|
|
@ -1427,6 +1425,7 @@
|
|||
"player.picture_in_picture": "Mini player",
|
||||
"player.settings": "Settings",
|
||||
"player.anime4k": "Anime4K",
|
||||
"player.stable_volume": "Stable Volume",
|
||||
"player.restore_window": "Restore window",
|
||||
"player.subtitle_delay_earlier": "Subtitles -0.1s",
|
||||
"player.subtitle_delay_later": "Subtitles +0.1s",
|
||||
|
|
|
|||
|
|
@ -696,8 +696,6 @@
|
|||
"settings.playback_speed_desc": "Videolar için normal oynatma hızını belirler.",
|
||||
"settings.resume_playback_desc": "Bir içeriği tekrar açtığında son kaydedilen yerden devam eder.",
|
||||
"settings.forward_rewind_desc": "İleri ve geri sarma düğmelerinin kaç saniye atlayacağını belirler.",
|
||||
"settings.stable_volume": "Sabit Ses Düzeyi",
|
||||
"settings.stable_volume_desc": "Yüksek ve alçak sesli anları dengeleyerek ses düzeyini tutarlı tutar.",
|
||||
"settings.hold_to_speed": "Basılı Tutunca Hızlandır",
|
||||
"settings.hold_to_speed_desc": "Videoya basılı tuttuğun sürece oynatmayı geçici olarak hızlandırır.",
|
||||
"settings.hold_speed": "Basılı Tutma Hızı",
|
||||
|
|
@ -1427,6 +1425,7 @@
|
|||
"player.picture_in_picture": "Mini oynatıcı",
|
||||
"player.settings": "Ayarlar",
|
||||
"player.anime4k": "Anime4K",
|
||||
"player.stable_volume": "Sabit Ses Düzeyi",
|
||||
"player.restore_window": "Pencereyi geri yükle",
|
||||
"player.subtitle_delay_earlier": "Altyazı -0.1s",
|
||||
"player.subtitle_delay_later": "Altyazı +0.1s",
|
||||
|
|
|
|||
Loading…
Reference in a new issue