mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 02:13:33 +00:00
Improved translations for English and Russian versions. (#760)
* First version of Russian translation * Improvements --------- Co-authored-by: Suoslex <mtsarev06@gmail.com>
This commit is contained in:
parent
8cddbef701
commit
7bcfe30a8e
21 changed files with 251 additions and 120 deletions
|
|
@ -37,7 +37,7 @@ const ActionRequiredRoute = () => {
|
|||
const handleManageServersModal = () => {
|
||||
openModal({
|
||||
children: <ServerList />,
|
||||
title: 'Manage Servers',
|
||||
title: t('page.appMenu.manageServers', { postProcess: 'sentenceCase' }),
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,9 @@ export const AlbumDetailHeader = forwardRef(
|
|||
},
|
||||
{
|
||||
id: 'songCount',
|
||||
value: `${detailQuery?.data?.songCount} songs`,
|
||||
value: t('entity.song_many', {
|
||||
count: detailQuery?.data?.songCount as number,
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: 'duration',
|
||||
|
|
|
|||
|
|
@ -511,7 +511,7 @@ export const AlbumListHeaderFilters = ({
|
|||
},
|
||||
}}
|
||||
tooltip={{
|
||||
label: t('common.filter', { count: 2, postProcess: 'sentenceCase' }),
|
||||
label: t('common.filters', { count: 2, postProcess: 'sentenceCase' }),
|
||||
}}
|
||||
variant="subtle"
|
||||
onClick={handleOpenFiltersModal}
|
||||
|
|
@ -589,7 +589,9 @@ export const AlbumListHeaderFilters = ({
|
|||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Label>Display type</DropdownMenu.Label>
|
||||
<DropdownMenu.Label>
|
||||
{t('table.config.general.displayType', { postProcess: 'sentenceCase' })}
|
||||
</DropdownMenu.Label>
|
||||
<DropdownMenu.Item
|
||||
$isActive={display === ListDisplayType.CARD}
|
||||
value={ListDisplayType.CARD}
|
||||
|
|
|
|||
|
|
@ -446,7 +446,9 @@ export const AlbumArtistListHeaderFilters = ({
|
|||
icon={<RiRefreshLine />}
|
||||
onClick={handleRefresh}
|
||||
>
|
||||
Refresh
|
||||
{t('common.refresh', {
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Dropdown>
|
||||
</DropdownMenu>
|
||||
|
|
@ -466,7 +468,9 @@ export const AlbumArtistListHeaderFilters = ({
|
|||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Label>Display type</DropdownMenu.Label>
|
||||
<DropdownMenu.Label>
|
||||
{t('table.config.general.displayType', { postProcess: 'sentenceCase' })}
|
||||
</DropdownMenu.Label>
|
||||
<DropdownMenu.Item
|
||||
$isActive={display === ListDisplayType.CARD}
|
||||
value={ListDisplayType.CARD}
|
||||
|
|
|
|||
|
|
@ -876,7 +876,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
},
|
||||
],
|
||||
id: 'setRating',
|
||||
label: 'Set rating',
|
||||
label: t('action.setRating', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiStarFill size="1.1rem" />,
|
||||
onClick: () => {},
|
||||
rightIcon: <RiArrowRightSFill size="1.2rem" />,
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ export const GenreListHeaderFilters = ({
|
|||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Label>
|
||||
{t('table.config.general.displayType', { postProcess: 'titleCase' })}
|
||||
{t('table.config.general.displayType', { postProcess: 'sentenceCase' })}
|
||||
</DropdownMenu.Label>
|
||||
<DropdownMenu.Item
|
||||
$isActive={display === ListDisplayType.CARD}
|
||||
|
|
@ -423,7 +423,11 @@ export const GenreListHeaderFilters = ({
|
|||
</DropdownMenu.Item>
|
||||
{isGrid && (
|
||||
<>
|
||||
<DropdownMenu.Label>Item gap</DropdownMenu.Label>
|
||||
<DropdownMenu.Label>
|
||||
{t('table.config.general.itemGap', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</DropdownMenu.Label>
|
||||
<DropdownMenu.Item closeMenuOnClick={false}>
|
||||
<Slider
|
||||
defaultValue={grid?.itemGap || 0}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import { Center, Group } from '@mantine/core';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RiInformationFill } from 'react-icons/ri';
|
||||
import styled from 'styled-components';
|
||||
import { useSongLyricsByRemoteId, useSongLyricsBySong } from './queries/lyric-query';
|
||||
|
|
@ -86,6 +87,7 @@ const ScrollContainer = styled(motion.div)`
|
|||
export const Lyrics = () => {
|
||||
const currentSong = useCurrentSong();
|
||||
const lyricsSettings = useLyricsSettings();
|
||||
const { t } = useTranslation();
|
||||
const [index, setIndex] = useState(0);
|
||||
const [translatedLyrics, setTranslatedLyrics] = useState<string | null>(null);
|
||||
const [showTranslation, setShowTranslation] = useState(false);
|
||||
|
|
@ -217,7 +219,9 @@ export const Lyrics = () => {
|
|||
order={3}
|
||||
weight={700}
|
||||
>
|
||||
No lyrics found
|
||||
{t('page.fullscreenPlayer.noLyrics', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</TextTitle>
|
||||
</Group>
|
||||
</Center>
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ export const FullScreenPlayerQueue = () => {
|
|||
items.push({
|
||||
active: activeTab === 'visualizer',
|
||||
icon: <RiFileTextLine size="1.5rem" />,
|
||||
label: t('page.fullscreenPlayer.visualizer'),
|
||||
label: t('page.fullscreenPlayer.visualizer', { postProcess: 'titleCase' }),
|
||||
onClick: () => setStore({ activeTab: 'visualizer' }),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,7 +382,11 @@ const Controls = () => {
|
|||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>Lyrics offset (ms)</Option.Label>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricOffset', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<NumberInput
|
||||
defaultValue={lyricConfig.delayMs}
|
||||
|
|
|
|||
|
|
@ -293,7 +293,10 @@ export const RightControls = () => {
|
|||
{!isMinWidth ? (
|
||||
<PlayerButton
|
||||
icon={<HiOutlineQueueList size="1.1rem" />}
|
||||
tooltip={{ label: 'View queue', openDelay: 500 }}
|
||||
tooltip={{
|
||||
label: t('player.viewQueue', { postProcess: 'titleCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="secondary"
|
||||
onClick={handleToggleQueue}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -596,7 +596,9 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
|||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Label>Display type</DropdownMenu.Label>
|
||||
<DropdownMenu.Label>
|
||||
{t('table.config.general.displayType', { postProcess: 'sentenceCase' })}
|
||||
</DropdownMenu.Label>
|
||||
<DropdownMenu.Item
|
||||
$isActive={page.display === ListDisplayType.TABLE}
|
||||
value={ListDisplayType.TABLE}
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ export const PlaylistListHeaderFilters = ({
|
|||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
<DropdownMenu.Label>
|
||||
{t('table.config.general.displayType', { postProcess: 'titleCase' })}
|
||||
{t('table.config.general.displayType', { postProcess: 'sentenceCase' })}
|
||||
</DropdownMenu.Label>
|
||||
<DropdownMenu.Item
|
||||
$isActive={display === ListDisplayType.CARD}
|
||||
|
|
|
|||
|
|
@ -467,11 +467,11 @@ export const PlaylistQueryBuilder = forwardRef(
|
|||
<Select
|
||||
data={[
|
||||
{
|
||||
label: t('common.ascending', { postProcess: 'titleCase' }),
|
||||
label: t('common.ascending', { postProcess: 'sentenceCase' }),
|
||||
value: 'asc',
|
||||
},
|
||||
{
|
||||
label: t('common.descending', { postProcess: 'titleCase' }),
|
||||
label: t('common.descending', { postProcess: 'sentenceCase' }),
|
||||
value: 'desc',
|
||||
},
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Stack, Group, Divider } from '@mantine/core';
|
|||
import { Button, Text, TimeoutButton } from '/@/renderer/components';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RiDeleteBin2Line, RiEdit2Fill } from 'react-icons/ri';
|
||||
import { EditServerForm } from '/@/renderer/features/servers/components/edit-server-form';
|
||||
import { ServerSection } from '/@/renderer/features/servers/components/server-section';
|
||||
|
|
@ -16,6 +17,7 @@ interface ServerListItemProps {
|
|||
}
|
||||
|
||||
export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [edit, editHandlers] = useDisclosure(false);
|
||||
const [savedPassword, setSavedPassword] = useState('');
|
||||
const { deleteServer } = useAuthStoreActions();
|
||||
|
|
@ -54,7 +56,11 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||
<ServerSection
|
||||
title={
|
||||
<Group position="apart">
|
||||
<Text>Server details</Text>
|
||||
<Text>
|
||||
{t('page.manageServers.serverDetails', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Text>
|
||||
</Group>
|
||||
}
|
||||
>
|
||||
|
|
@ -68,8 +74,16 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||
<Stack>
|
||||
<Group noWrap>
|
||||
<Stack>
|
||||
<Text>URL</Text>
|
||||
<Text>Username</Text>
|
||||
<Text>
|
||||
{t('page.manageServers.url', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Text>
|
||||
<Text>
|
||||
{t('page.manageServers.username', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<Text>{server.url}</Text>
|
||||
|
|
@ -79,11 +93,15 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||
<Group grow>
|
||||
<Button
|
||||
leftIcon={<RiEdit2Fill />}
|
||||
tooltip={{ label: 'Edit server details' }}
|
||||
tooltip={{
|
||||
label: t('page.manageServers.editServerDetailsTooltip', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
}}
|
||||
variant="subtle"
|
||||
onClick={() => handleEdit()}
|
||||
>
|
||||
Edit
|
||||
{t('common.edit')}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
|
@ -95,7 +113,7 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||
timeoutProps={{ callback: handleDeleteServer, duration: 1000 }}
|
||||
variant="subtle"
|
||||
>
|
||||
Remove server
|
||||
{t('page.manageServers.removeServer', { postProcess: 'sentenceCase' })}
|
||||
</TimeoutButton>
|
||||
</Stack>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ export const OrderToggleButton = ({ sortOrder, onToggle, buttonProps }: OrderTog
|
|||
<Tooltip
|
||||
label={
|
||||
sortOrder === SortOrder.ASC
|
||||
? t('common.ascending', { postProcess: 'titleCase' })
|
||||
: t('common.descending', { postProcess: 'titleCase' })
|
||||
? t('common.ascending', { postProcess: 'sentenceCase' })
|
||||
: t('common.descending', { postProcess: 'sentenceCase' })
|
||||
}
|
||||
>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -609,7 +609,7 @@ export const SongListHeaderFilters = ({
|
|||
icon={<RiRefreshLine />}
|
||||
onClick={handleRefresh}
|
||||
>
|
||||
Refresh
|
||||
{t('common.refresh', { postProcess: 'titleCase' })}
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Dropdown>
|
||||
</DropdownMenu>
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export const AppMenu = () => {
|
|||
const handleManageServersModal = () => {
|
||||
openModal({
|
||||
children: <ServerList />,
|
||||
title: 'Manage Servers',
|
||||
title: t('page.manageServers.title', { postProcess: 'titleCase' }),
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue