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:
Mikhail Tsarev 2024-09-26 12:42:41 +08:00 committed by GitHub
parent 8cddbef701
commit 7bcfe30a8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 251 additions and 120 deletions

View file

@ -37,7 +37,7 @@ const ActionRequiredRoute = () => {
const handleManageServersModal = () => {
openModal({
children: <ServerList />,
title: 'Manage Servers',
title: t('page.appMenu.manageServers', { postProcess: 'sentenceCase' }),
});
};

View file

@ -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',

View file

@ -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}

View file

@ -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}

View file

@ -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" />,

View file

@ -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}

View file

@ -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>

View file

@ -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' }),
});
}

View file

@ -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}

View file

@ -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}
/>

View file

@ -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}

View file

@ -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}

View file

@ -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',
},
]}

View file

@ -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>
);

View file

@ -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

View file

@ -609,7 +609,7 @@ export const SongListHeaderFilters = ({
icon={<RiRefreshLine />}
onClick={handleRefresh}
>
Refresh
{t('common.refresh', { postProcess: 'titleCase' })}
</DropdownMenu.Item>
</DropdownMenu.Dropdown>
</DropdownMenu>

View file

@ -76,7 +76,7 @@ export const AppMenu = () => {
const handleManageServersModal = () => {
openModal({
children: <ServerList />,
title: 'Manage Servers',
title: t('page.manageServers.title', { postProcess: 'titleCase' }),
});
};