mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 02:13:33 +00:00
Add localization support (#333)
* Add updated i18n config and en locale
This commit is contained in:
parent
11863fd4c1
commit
8430b1ec95
90 changed files with 2679 additions and 908 deletions
|
|
@ -3,6 +3,7 @@ import { useHotkeys } from '@mantine/hooks';
|
|||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import formatDuration from 'format-duration';
|
||||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IoIosPause } from 'react-icons/io';
|
||||
import {
|
||||
RiMenuAddFill,
|
||||
|
|
@ -92,6 +93,7 @@ const ControlsContainer = styled.div`
|
|||
`;
|
||||
|
||||
export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
const [isSeeking, setIsSeeking] = useState(false);
|
||||
const currentSong = useCurrentSong();
|
||||
|
|
@ -171,7 +173,7 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
<PlayerButton
|
||||
icon={<RiStopFill size={15} />}
|
||||
tooltip={{
|
||||
label: 'Stop',
|
||||
label: t('player.stop', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="tertiary"
|
||||
|
|
@ -183,10 +185,11 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
tooltip={{
|
||||
label:
|
||||
shuffle === PlayerShuffle.NONE
|
||||
? 'Shuffle disabled'
|
||||
: shuffle === PlayerShuffle.TRACK
|
||||
? 'Shuffle tracks'
|
||||
: 'Shuffle albums',
|
||||
? t('player.shuffle', {
|
||||
context: 'off',
|
||||
postProcess: 'sentenceCase',
|
||||
})
|
||||
: t('player.shuffle', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="tertiary"
|
||||
|
|
@ -194,7 +197,10 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
/>
|
||||
<PlayerButton
|
||||
icon={<RiSkipBackFill size={15} />}
|
||||
tooltip={{ label: 'Previous track', openDelay: 500 }}
|
||||
tooltip={{
|
||||
label: t('player.previous', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="secondary"
|
||||
onClick={handlePrevTrack}
|
||||
/>
|
||||
|
|
@ -202,7 +208,10 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
<PlayerButton
|
||||
icon={<RiRewindFill size={15} />}
|
||||
tooltip={{
|
||||
label: `Skip backwards ${skip?.skipBackwardSeconds} seconds`,
|
||||
label: t('player.skip', {
|
||||
context: 'back',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="secondary"
|
||||
|
|
@ -218,7 +227,10 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
)
|
||||
}
|
||||
tooltip={{
|
||||
label: status === PlayerStatus.PAUSED ? 'Play' : 'Pause',
|
||||
label:
|
||||
status === PlayerStatus.PAUSED
|
||||
? t('player.play', { postProcess: 'sentenceCase' })
|
||||
: t('player.pause', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="main"
|
||||
|
|
@ -228,7 +240,10 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
<PlayerButton
|
||||
icon={<RiSpeedFill size={15} />}
|
||||
tooltip={{
|
||||
label: `Skip forwards ${skip?.skipForwardSeconds} seconds`,
|
||||
label: t('player.stop', {
|
||||
context: 'forward',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="secondary"
|
||||
|
|
@ -237,7 +252,10 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
)}
|
||||
<PlayerButton
|
||||
icon={<RiSkipForwardFill size={15} />}
|
||||
tooltip={{ label: 'Next track', openDelay: 500 }}
|
||||
tooltip={{
|
||||
label: t('player.next', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="secondary"
|
||||
onClick={handleNextTrack}
|
||||
/>
|
||||
|
|
@ -253,10 +271,19 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
tooltip={{
|
||||
label: `${
|
||||
repeat === PlayerRepeat.NONE
|
||||
? 'Repeat disabled'
|
||||
? t('player.repeat', {
|
||||
context: 'off',
|
||||
postProcess: 'sentenceCase',
|
||||
})
|
||||
: repeat === PlayerRepeat.ALL
|
||||
? 'Repeat all'
|
||||
: 'Repeat one'
|
||||
? t('player.repeat', {
|
||||
context: 'all',
|
||||
postProcess: 'sentenceCase',
|
||||
})
|
||||
: t('player.repeat', {
|
||||
context: 'one',
|
||||
postProcess: 'sentenceCase',
|
||||
})
|
||||
}`,
|
||||
openDelay: 500,
|
||||
}}
|
||||
|
|
@ -267,7 +294,7 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
<PlayerButton
|
||||
icon={<RiMenuAddFill size={15} />}
|
||||
tooltip={{
|
||||
label: 'Shuffle all',
|
||||
label: t('player.playRandom', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="tertiary"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Group, Center } from '@mantine/core';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { HiOutlineQueueList } from 'react-icons/hi2';
|
||||
import { RiFileMusicLine, RiFileTextLine, RiInformationFill } from 'react-icons/ri';
|
||||
import styled from 'styled-components';
|
||||
|
|
@ -50,11 +51,12 @@ const GridContainer = styled.div<TransparendGridContainerProps>`
|
|||
grid-template-rows: auto minmax(0, 1fr);
|
||||
grid-template-columns: 1fr;
|
||||
padding: 1rem;
|
||||
background: rgb(var(--main-bg-transparent), ${({ opacity }) => opacity}%);
|
||||
background: rgb(var(--main-bg-transparent) ${({ opacity }) => opacity}%);
|
||||
border-radius: 5px;
|
||||
`;
|
||||
|
||||
export const FullScreenPlayerQueue = () => {
|
||||
const { t } = useTranslation();
|
||||
const { activeTab, opacity } = useFullScreenPlayerStore();
|
||||
const { setStore } = useFullScreenPlayerStoreActions();
|
||||
|
||||
|
|
@ -62,19 +64,19 @@ export const FullScreenPlayerQueue = () => {
|
|||
{
|
||||
active: activeTab === 'queue',
|
||||
icon: <RiFileMusicLine size="1.5rem" />,
|
||||
label: 'Up Next',
|
||||
label: t('page.fullScreenPlayer.upNext'),
|
||||
onClick: () => setStore({ activeTab: 'queue' }),
|
||||
},
|
||||
{
|
||||
active: activeTab === 'related',
|
||||
icon: <HiOutlineQueueList size="1.5rem" />,
|
||||
label: 'Related',
|
||||
label: t('page.fullScreenPlayer.related'),
|
||||
onClick: () => setStore({ activeTab: 'related' }),
|
||||
},
|
||||
{
|
||||
active: activeTab === 'lyrics',
|
||||
icon: <RiFileTextLine size="1.5rem" />,
|
||||
label: 'Lyrics',
|
||||
label: t('page.fullScreenPlayer.lyrics'),
|
||||
onClick: () => setStore({ activeTab: 'lyrics' }),
|
||||
},
|
||||
];
|
||||
|
|
@ -125,7 +127,7 @@ export const FullScreenPlayerQueue = () => {
|
|||
order={3}
|
||||
weight={700}
|
||||
>
|
||||
COMING SOON
|
||||
{t('common.comingSoon', { postProcess: 'upperCase' })}
|
||||
</TextTitle>
|
||||
</Group>
|
||||
</Center>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useLayoutEffect, useRef } from 'react';
|
|||
import { Divider, Group } from '@mantine/core';
|
||||
import { useHotkeys } from '@mantine/hooks';
|
||||
import { Variants, motion } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RiArrowDownSLine, RiSettings3Line } from 'react-icons/ri';
|
||||
import { useLocation } from 'react-router';
|
||||
import styled from 'styled-components';
|
||||
|
|
@ -70,6 +71,7 @@ const BackgroundImageOverlay = styled.div`
|
|||
`;
|
||||
|
||||
const Controls = () => {
|
||||
const { t } = useTranslation();
|
||||
const { dynamicBackground, expanded, opacity, useImageAspectRatio } =
|
||||
useFullScreenPlayerStore();
|
||||
const { setStore } = useFullScreenPlayerStoreActions();
|
||||
|
|
@ -104,7 +106,7 @@ const Controls = () => {
|
|||
<Button
|
||||
compact
|
||||
size="sm"
|
||||
tooltip={{ label: 'Minimize' }}
|
||||
tooltip={{ label: t('common.minimize', { postProcess: 'titleCase' }) }}
|
||||
variant="subtle"
|
||||
onClick={handleToggleFullScreenPlayer}
|
||||
>
|
||||
|
|
@ -115,7 +117,7 @@ const Controls = () => {
|
|||
<Button
|
||||
compact
|
||||
size="sm"
|
||||
tooltip={{ label: 'Configure' }}
|
||||
tooltip={{ label: t('common.configure', { postProcess: 'titleCase' }) }}
|
||||
variant="subtle"
|
||||
>
|
||||
<RiSettings3Line size="1.5rem" />
|
||||
|
|
@ -123,7 +125,11 @@ const Controls = () => {
|
|||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
<Option>
|
||||
<Option.Label>Dynamic Background</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.dynamicBackground', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
defaultChecked={dynamicBackground}
|
||||
|
|
@ -137,7 +143,11 @@ const Controls = () => {
|
|||
</Option>
|
||||
{dynamicBackground && (
|
||||
<Option>
|
||||
<Option.Label>Opacity</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.opacity', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
defaultValue={opacity}
|
||||
|
|
@ -151,7 +161,11 @@ const Controls = () => {
|
|||
</Option>
|
||||
)}
|
||||
<Option>
|
||||
<Option.Label>Use image aspect ratio</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.useImageAspectRatio', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
checked={useImageAspectRatio}
|
||||
|
|
@ -165,7 +179,11 @@ const Controls = () => {
|
|||
</Option>
|
||||
<Divider my="sm" />
|
||||
<Option>
|
||||
<Option.Label>Follow current lyrics</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.followCurrentLyric', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
checked={lyricConfig.follow}
|
||||
|
|
@ -176,7 +194,11 @@ const Controls = () => {
|
|||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>Show lyrics provider</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.showLyricProvider', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
checked={lyricConfig.showProvider}
|
||||
|
|
@ -187,7 +209,11 @@ const Controls = () => {
|
|||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>Show lyrics match</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.showLyricMatch', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
checked={lyricConfig.showMatch}
|
||||
|
|
@ -198,7 +224,11 @@ const Controls = () => {
|
|||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>Lyrics size</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.lyric', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Group
|
||||
noWrap
|
||||
|
|
@ -206,7 +236,11 @@ const Controls = () => {
|
|||
>
|
||||
<Slider
|
||||
defaultValue={lyricConfig.fontSize}
|
||||
label={(e) => `Synchronized: ${e}px`}
|
||||
label={(e) =>
|
||||
`${t('page.fullscreenPlayer.synchronized', {
|
||||
postProcess: 'titleCase',
|
||||
})}: ${e}px`
|
||||
}
|
||||
max={72}
|
||||
min={8}
|
||||
w="100%"
|
||||
|
|
@ -214,7 +248,11 @@ const Controls = () => {
|
|||
/>
|
||||
<Slider
|
||||
defaultValue={lyricConfig.fontSize}
|
||||
label={(e) => `Unsynchronized: ${e}px`}
|
||||
label={(e) =>
|
||||
`${t('page.fullscreenPlayer.unsynchronized', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}: ${e}px`
|
||||
}
|
||||
max={72}
|
||||
min={8}
|
||||
w="100%"
|
||||
|
|
@ -226,7 +264,11 @@ const Controls = () => {
|
|||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>Lyrics gap</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.lyricGap', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Group
|
||||
noWrap
|
||||
|
|
@ -254,13 +296,32 @@ const Controls = () => {
|
|||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>Lyrics alignment</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.lyricAlignment', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Select
|
||||
data={[
|
||||
{ label: 'Left', value: 'left' },
|
||||
{ label: 'Center', value: 'center' },
|
||||
{ label: 'Right', value: 'right' },
|
||||
{
|
||||
label: t('common.left', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
value: 'left',
|
||||
},
|
||||
{
|
||||
label: t('common.center', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
value: 'center',
|
||||
},
|
||||
{
|
||||
label: t('common.right', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
value: 'right',
|
||||
},
|
||||
]}
|
||||
value={lyricConfig.alignment}
|
||||
onChange={(e) => handleLyricsSettings('alignment', e)}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React, { MouseEvent } from 'react';
|
|||
import { Center, Group } from '@mantine/core';
|
||||
import { useHotkeys } from '@mantine/hooks';
|
||||
import { motion, AnimatePresence, LayoutGroup } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RiArrowUpSLine, RiDiscLine, RiMore2Fill } from 'react-icons/ri';
|
||||
import { generatePath, Link } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
|
|
@ -92,6 +93,7 @@ const LeftControlsContainer = styled.div`
|
|||
`;
|
||||
|
||||
export const LeftControls = () => {
|
||||
const { t } = useTranslation();
|
||||
const { setSideBar } = useAppStoreActions();
|
||||
const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore();
|
||||
const setFullScreenPlayerStore = useSetFullScreenPlayerStore();
|
||||
|
|
@ -147,7 +149,9 @@ export const LeftControls = () => {
|
|||
onClick={handleToggleFullScreenPlayer}
|
||||
>
|
||||
<Tooltip
|
||||
label="Toggle fullscreen player"
|
||||
label={t('player.toggleFullscreenPlayer', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
openDelay={500}
|
||||
>
|
||||
{currentSong?.imageUrl ? (
|
||||
|
|
@ -182,7 +186,12 @@ export const LeftControls = () => {
|
|||
right: 2,
|
||||
top: 2,
|
||||
}}
|
||||
tooltip={{ label: 'Expand', openDelay: 500 }}
|
||||
tooltip={{
|
||||
label: t('common.expand', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="default"
|
||||
onClick={handleToggleSidebarImage}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useEffect } from 'react';
|
|||
import { Flex, Group } from '@mantine/core';
|
||||
import { useHotkeys, useMediaQuery } from '@mantine/hooks';
|
||||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { HiOutlineQueueList } from 'react-icons/hi2';
|
||||
import {
|
||||
RiVolumeUpFill,
|
||||
|
|
@ -34,6 +35,7 @@ const remote = isElectron() ? window.electron.remote : null;
|
|||
const PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0];
|
||||
|
||||
export const RightControls = () => {
|
||||
const { t } = useTranslation();
|
||||
const isMinWidth = useMediaQuery('(max-width: 480px)');
|
||||
const volume = useVolume();
|
||||
const muted = useMuted();
|
||||
|
|
@ -213,7 +215,7 @@ export const RightControls = () => {
|
|||
<PlayerButton
|
||||
icon={<>{speed} x</>}
|
||||
tooltip={{
|
||||
label: 'Playback speed',
|
||||
label: t('player.playbackSpeed', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="secondary"
|
||||
|
|
@ -249,7 +251,9 @@ export const RightControls = () => {
|
|||
},
|
||||
}}
|
||||
tooltip={{
|
||||
label: currentSong?.userFavorite ? 'Unfavorite' : 'Favorite',
|
||||
label: currentSong?.userFavorite
|
||||
? t('player.unfavorite', { postProcess: 'titleCase' })
|
||||
: t('player.favorite', { postProcess: 'titleCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="secondary"
|
||||
|
|
@ -277,7 +281,10 @@ export const RightControls = () => {
|
|||
<RiVolumeDownFill size="1.2rem" />
|
||||
)
|
||||
}
|
||||
tooltip={{ label: muted ? 'Muted' : volume, openDelay: 500 }}
|
||||
tooltip={{
|
||||
label: muted ? t('player.muted', { postProcess: 'titleCase' }) : volume,
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="secondary"
|
||||
onClick={handleMute}
|
||||
onWheel={handleVolumeWheel}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import { api } from '/@/renderer/api';
|
|||
import { useAuthStore } from '/@/renderer/store';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { Play, PlayQueueAddOptions, ServerListItem } from '/@/renderer/types';
|
||||
import i18n from '/@/i18n/i18n';
|
||||
|
||||
interface ShuffleAllSlice extends RandomSongListQuery {
|
||||
actions: {
|
||||
|
|
@ -260,6 +261,6 @@ export const openShuffleAllModal = async (
|
|||
/>
|
||||
),
|
||||
size: 'sm',
|
||||
title: 'Shuffle all',
|
||||
title: i18n.t('player.playRandom', { postProcess: 'sentenceCase' }) as string,
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import { useScrobble } from '/@/renderer/features/player/hooks/use-scrobble';
|
|||
import debounce from 'lodash/debounce';
|
||||
import { QueueSong } from '/@/renderer/api/types';
|
||||
import { toast } from '/@/renderer/components';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null;
|
||||
const mpvPlayerListener = isElectron() ? window.electron.mpvPlayerListener : null;
|
||||
|
|
@ -28,6 +29,7 @@ const remote = isElectron() ? window.electron.remote : null;
|
|||
const mediaSession = !isElectron() || !utils?.isLinux() ? navigator.mediaSession : null;
|
||||
|
||||
export const useCenterControls = (args: { playersRef: any }) => {
|
||||
const { t } = useTranslation();
|
||||
const { playersRef } = args;
|
||||
|
||||
const settings = useSettingsStore((state) => state.playback);
|
||||
|
|
@ -613,11 +615,15 @@ export const useCenterControls = (args: { playersRef: any }) => {
|
|||
|
||||
const handleError = useCallback(
|
||||
(message: string) => {
|
||||
toast.error({ id: 'mpv-error', message, title: 'An error occurred during playback' });
|
||||
toast.error({
|
||||
id: 'mpv-error',
|
||||
message,
|
||||
title: t('error.playbackError', { postProcess: 'sentenceCase' }),
|
||||
});
|
||||
pause();
|
||||
mpvPlayer!.pause();
|
||||
},
|
||||
[pause],
|
||||
[pause, t],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import {
|
|||
getGenreSongsById,
|
||||
} from '/@/renderer/features/player/utils';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const getRootQueryKey = (itemType: LibraryItem, serverId: string) => {
|
||||
let queryKey;
|
||||
|
|
@ -62,6 +63,7 @@ const remote = isElectron() ? window.electron.remote : null;
|
|||
const addToQueue = usePlayerStore.getState().actions.addToQueue;
|
||||
|
||||
export const useHandlePlayQueueAdd = () => {
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
const playerType = usePlayerType();
|
||||
const server = useCurrentServer();
|
||||
|
|
@ -86,15 +88,18 @@ export const useHandlePlayQueueAdd = () => {
|
|||
toast.info({
|
||||
autoClose: false,
|
||||
id: fetchId,
|
||||
message:
|
||||
'This is taking a while... close the notification to cancel the request',
|
||||
message: t('player.playbackFetchCancel', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
onClose: () => {
|
||||
queryClient.cancelQueries({
|
||||
exact: false,
|
||||
queryKey: getRootQueryKey(itemType, server?.id),
|
||||
});
|
||||
},
|
||||
title: 'Adding to queue',
|
||||
title: t('player.playbackFetchInProgress', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
});
|
||||
}, 2000),
|
||||
};
|
||||
|
|
@ -140,7 +145,7 @@ export const useHandlePlayQueueAdd = () => {
|
|||
|
||||
return toast.error({
|
||||
message: err.message,
|
||||
title: 'Play queue add failed',
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }) as string,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -152,8 +157,8 @@ export const useHandlePlayQueueAdd = () => {
|
|||
|
||||
if (!songs || songs?.length === 0)
|
||||
return toast.warn({
|
||||
message: 'The query returned no results',
|
||||
title: 'No tracks added',
|
||||
message: t('common.noResultsFromQuery', { postProcess: 'sentenceCase' }),
|
||||
title: t('player.playbackFetchNoResults'),
|
||||
});
|
||||
|
||||
if (initialIndex) {
|
||||
|
|
@ -190,7 +195,7 @@ export const useHandlePlayQueueAdd = () => {
|
|||
|
||||
return null;
|
||||
},
|
||||
[play, playerType, queryClient, server],
|
||||
[play, playerType, queryClient, server, t],
|
||||
);
|
||||
|
||||
return handlePlayQueueAdd;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue