mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-16 05:36:00 +02:00
add setting to follow current song on playqueue
This commit is contained in:
@@ -682,6 +682,8 @@
|
|||||||
"exportImportSettings_offendingKeyError": "\"{{offendingKey}}\" is incorrect - {{reason}}",
|
"exportImportSettings_offendingKeyError": "\"{{offendingKey}}\" is incorrect - {{reason}}",
|
||||||
"externalLinks_description": "enables showing external links (Last.fm, MusicBrainz) on artist/album pages",
|
"externalLinks_description": "enables showing external links (Last.fm, MusicBrainz) on artist/album pages",
|
||||||
"externalLinks": "show external links",
|
"externalLinks": "show external links",
|
||||||
|
"followCurrentSong_description": "automatically scroll the play queue to the current playing song",
|
||||||
|
"followCurrentSong": "follow current song",
|
||||||
"followLyric_description": "scroll the lyric to the current playing position",
|
"followLyric_description": "scroll the lyric to the current playing position",
|
||||||
"followLyric": "follow current lyric",
|
"followLyric": "follow current lyric",
|
||||||
"font_description": "sets the font to use for the application",
|
"font_description": "sets the font to use for the application",
|
||||||
@@ -779,7 +781,8 @@
|
|||||||
"playerAlbumArtResolution": "player album art resolution",
|
"playerAlbumArtResolution": "player album art resolution",
|
||||||
"playerbarOpenDrawer_description": "allows clicking of the playerbar to open the full screen player",
|
"playerbarOpenDrawer_description": "allows clicking of the playerbar to open the full screen player",
|
||||||
"playerbarOpenDrawer": "playerbar fullscreen toggle",
|
"playerbarOpenDrawer": "playerbar fullscreen toggle",
|
||||||
"playerbarSlider": "playerbar slider - the waveform is not recommended if using on a slow or metered internet connection",
|
"playerbarSlider": "playerbar slider",
|
||||||
|
"playerbarSlider_description": "the waveform is not recommended if on a slow or metered internet connection",
|
||||||
"playerbarSliderType_optionSlider": "slider",
|
"playerbarSliderType_optionSlider": "slider",
|
||||||
"playerbarSliderType_optionWaveform": "waveform",
|
"playerbarSliderType_optionWaveform": "waveform",
|
||||||
"playerbarWaveformAlign": "waveform align",
|
"playerbarWaveformAlign": "waveform align",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
usePlayerActions,
|
usePlayerActions,
|
||||||
usePlayerQueueType,
|
usePlayerQueueType,
|
||||||
usePlayerSong,
|
usePlayerSong,
|
||||||
|
useSettingsStore,
|
||||||
} from '/@/renderer/store';
|
} from '/@/renderer/store';
|
||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { LoadingOverlay } from '/@/shared/components/loading-overlay/loading-overlay';
|
import { LoadingOverlay } from '/@/shared/components/loading-overlay/loading-overlay';
|
||||||
@@ -46,6 +47,7 @@ export const PlayQueue = forwardRef<ItemListHandle, QueueProps>(({ listKey, sear
|
|||||||
const mergedRef = useMergedRef(ref, tableRef);
|
const mergedRef = useMergedRef(ref, tableRef);
|
||||||
const { getQueue } = usePlayerActions();
|
const { getQueue } = usePlayerActions();
|
||||||
const queueType = usePlayerQueueType();
|
const queueType = usePlayerQueueType();
|
||||||
|
const followCurrentSong = useSettingsStore((state) => state.general.followCurrentSong);
|
||||||
|
|
||||||
const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 200);
|
const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 200);
|
||||||
|
|
||||||
@@ -91,10 +93,10 @@ export const PlayQueue = forwardRef<ItemListHandle, QueueProps>(({ listKey, sear
|
|||||||
});
|
});
|
||||||
|
|
||||||
const unsubCurrentTrack = subscribeCurrentTrack((e) => {
|
const unsubCurrentTrack = subscribeCurrentTrack((e) => {
|
||||||
if (e.index !== -1) {
|
if (followCurrentSong && e.index !== -1) {
|
||||||
tableRef.current?.scrollToIndex(e.index, {
|
tableRef.current?.scrollToIndex(e.index, {
|
||||||
align: 'top',
|
align: 'center',
|
||||||
behavior: 'smooth',
|
behavior: 'auto',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -105,7 +107,7 @@ export const PlayQueue = forwardRef<ItemListHandle, QueueProps>(({ listKey, sear
|
|||||||
unsub();
|
unsub();
|
||||||
unsubCurrentTrack();
|
unsubCurrentTrack();
|
||||||
};
|
};
|
||||||
}, [getQueue, queueType, tableRef]);
|
}, [getQueue, queueType, tableRef, followCurrentSong]);
|
||||||
|
|
||||||
const filteredData: QueueSong[] = useMemo(() => {
|
const filteredData: QueueSong[] = useMemo(() => {
|
||||||
if (debouncedSearchTerm) {
|
if (debouncedSearchTerm) {
|
||||||
@@ -127,6 +129,7 @@ export const PlayQueue = forwardRef<ItemListHandle, QueueProps>(({ listKey, sear
|
|||||||
});
|
});
|
||||||
|
|
||||||
const currentSong = usePlayerSong();
|
const currentSong = usePlayerSong();
|
||||||
|
|
||||||
const currentSongUniqueId = currentSong?._uniqueId;
|
const currentSongUniqueId = currentSong?._uniqueId;
|
||||||
|
|
||||||
const { focused, ref: containerFocusRef } = useFocusWithin();
|
const { focused, ref: containerFocusRef } = useFocusWithin();
|
||||||
|
|||||||
@@ -185,6 +185,28 @@ export const ControlSettings = () => {
|
|||||||
isHidden: false,
|
isHidden: false,
|
||||||
title: t('setting.playButtonBehavior', { postProcess: 'sentenceCase' }),
|
title: t('setting.playButtonBehavior', { postProcess: 'sentenceCase' }),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
control: (
|
||||||
|
<Switch
|
||||||
|
aria-label="Follow current song"
|
||||||
|
defaultChecked={settings.followCurrentSong}
|
||||||
|
onChange={(e) =>
|
||||||
|
setSettings({
|
||||||
|
general: {
|
||||||
|
...settings,
|
||||||
|
followCurrentSong: e.currentTarget.checked,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
description: t('setting.followCurrentSong', {
|
||||||
|
context: 'description',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
|
isHidden: false,
|
||||||
|
title: t('setting.followCurrentSong', { postProcess: 'sentenceCase' }),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
control: (
|
control: (
|
||||||
<Slider
|
<Slider
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ const GeneralSettingsSchema = z.object({
|
|||||||
buttonSize: z.number(),
|
buttonSize: z.number(),
|
||||||
disabledContextMenu: z.record(z.string(), z.boolean()),
|
disabledContextMenu: z.record(z.string(), z.boolean()),
|
||||||
externalLinks: z.boolean(),
|
externalLinks: z.boolean(),
|
||||||
|
followCurrentSong: z.boolean(),
|
||||||
followSystemTheme: z.boolean(),
|
followSystemTheme: z.boolean(),
|
||||||
genreTarget: GenreTargetSchema,
|
genreTarget: GenreTargetSchema,
|
||||||
homeFeature: z.boolean(),
|
homeFeature: z.boolean(),
|
||||||
@@ -634,6 +635,7 @@ const initialState: SettingsState = {
|
|||||||
buttonSize: 15,
|
buttonSize: 15,
|
||||||
disabledContextMenu: {},
|
disabledContextMenu: {},
|
||||||
externalLinks: true,
|
externalLinks: true,
|
||||||
|
followCurrentSong: true,
|
||||||
followSystemTheme: false,
|
followSystemTheme: false,
|
||||||
genreTarget: GenreTarget.TRACK,
|
genreTarget: GenreTarget.TRACK,
|
||||||
homeFeature: true,
|
homeFeature: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user