mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-09 20:29:36 +02:00
remove direct references to plural translation keys
This commit is contained in:
@@ -35,8 +35,8 @@ export const AlbumListHeaderFilters = ({ toggleGenreTarget }: { toggleGenreTarge
|
|||||||
|
|
||||||
const choice = useMemo(() => {
|
const choice = useMemo(() => {
|
||||||
return target === GenreTarget.ALBUM
|
return target === GenreTarget.ALBUM
|
||||||
? t('entity.album_other', { postProcess: 'titleCase' })
|
? t('entity.album', { count: 2, postProcess: 'titleCase' })
|
||||||
: t('entity.track_other', { postProcess: 'titleCase' });
|
: t('entity.track', { count: 2, postProcess: 'titleCase' });
|
||||||
}, [target, t]);
|
}, [target, t]);
|
||||||
|
|
||||||
const handleToggleGenreTarget = useCallback(() => {
|
const handleToggleGenreTarget = useCallback(() => {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ interface ArtistListHeaderProps {
|
|||||||
export const ArtistListHeader = ({ title }: ArtistListHeaderProps) => {
|
export const ArtistListHeader = ({ title }: ArtistListHeaderProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const pageTitle = title || t('entity.artist_other', { postProcess: 'titleCase' });
|
const pageTitle = title || t('entity.artist', { count: 2, postProcess: 'titleCase' });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap={0}>
|
<Stack gap={0}>
|
||||||
|
|||||||
@@ -87,15 +87,18 @@ export const FavoritesHeader = ({ itemType }: FavoritesHeaderProps) => {
|
|||||||
</Group>
|
</Group>
|
||||||
<Text isMuted size="sm">
|
<Text isMuted size="sm">
|
||||||
{itemType === LibraryItem.ALBUM &&
|
{itemType === LibraryItem.ALBUM &&
|
||||||
t('entity.album_other', {
|
t('entity.album', {
|
||||||
|
count: 2,
|
||||||
postProcess: 'sentenceCase',
|
postProcess: 'sentenceCase',
|
||||||
})}
|
})}
|
||||||
{itemType === LibraryItem.ALBUM_ARTIST &&
|
{itemType === LibraryItem.ALBUM_ARTIST &&
|
||||||
t('entity.artist_other', {
|
t('entity.artist', {
|
||||||
|
count: 2,
|
||||||
postProcess: 'sentenceCase',
|
postProcess: 'sentenceCase',
|
||||||
})}
|
})}
|
||||||
{itemType === LibraryItem.SONG &&
|
{itemType === LibraryItem.SONG &&
|
||||||
t('entity.track_other', {
|
t('entity.track', {
|
||||||
|
count: 2,
|
||||||
postProcess: 'sentenceCase',
|
postProcess: 'sentenceCase',
|
||||||
})}
|
})}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -107,14 +110,20 @@ export const FavoritesHeader = ({ itemType }: FavoritesHeaderProps) => {
|
|||||||
leftSection={<Icon icon="track" size="xl" />}
|
leftSection={<Icon icon="track" size="xl" />}
|
||||||
onClick={() => handleItemTypeChange(LibraryItem.SONG)}
|
onClick={() => handleItemTypeChange(LibraryItem.SONG)}
|
||||||
>
|
>
|
||||||
{t('entity.track_other', { postProcess: 'sentenceCase' })}
|
{t('entity.track', {
|
||||||
|
count: 2,
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
isSelected={itemType === LibraryItem.ALBUM}
|
isSelected={itemType === LibraryItem.ALBUM}
|
||||||
leftSection={<Icon icon="album" size="xl" />}
|
leftSection={<Icon icon="album" size="xl" />}
|
||||||
onClick={() => handleItemTypeChange(LibraryItem.ALBUM)}
|
onClick={() => handleItemTypeChange(LibraryItem.ALBUM)}
|
||||||
>
|
>
|
||||||
{t('entity.album_other', { postProcess: 'sentenceCase' })}
|
{t('entity.album', {
|
||||||
|
count: 2,
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
isSelected={itemType === LibraryItem.ALBUM_ARTIST}
|
isSelected={itemType === LibraryItem.ALBUM_ARTIST}
|
||||||
@@ -123,7 +132,10 @@ export const FavoritesHeader = ({ itemType }: FavoritesHeaderProps) => {
|
|||||||
handleItemTypeChange(LibraryItem.ALBUM_ARTIST)
|
handleItemTypeChange(LibraryItem.ALBUM_ARTIST)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{t('entity.artist_other', { postProcess: 'sentenceCase' })}
|
{t('entity.artist', {
|
||||||
|
count: 2,
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
</DropdownMenu.Dropdown>
|
</DropdownMenu.Dropdown>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ export const FeaturedGenres = () => {
|
|||||||
<>
|
<>
|
||||||
<Group align="flex-end" justify="space-between">
|
<Group align="flex-end" justify="space-between">
|
||||||
<TextTitle fw={700} isNoSelect order={3}>
|
<TextTitle fw={700} isNoSelect order={3}>
|
||||||
{t('entity.genre_other', { postProcess: 'titleCase' })}
|
{t('entity.genre', { count: 2, postProcess: 'titleCase' })}
|
||||||
</TextTitle>
|
</TextTitle>
|
||||||
<Button
|
<Button
|
||||||
component={Link}
|
component={Link}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export type ItemDetailsModalProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type ItemDetailRow<T> = {
|
type ItemDetailRow<T> = {
|
||||||
|
count?: number;
|
||||||
key?: keyof T;
|
key?: keyof T;
|
||||||
label: string;
|
label: string;
|
||||||
postprocess?: string[];
|
postprocess?: string[];
|
||||||
@@ -61,7 +62,10 @@ const handleRow = <T extends AnyLibraryItem>(
|
|||||||
return (
|
return (
|
||||||
<Table.Tr key={rule.label}>
|
<Table.Tr key={rule.label}>
|
||||||
<Table.Th>
|
<Table.Th>
|
||||||
{t(rule.label, { postProcess: rule.postprocess || 'sentenceCase' })}
|
{t(rule.label, {
|
||||||
|
...(rule.count !== undefined && { count: rule.count }),
|
||||||
|
postProcess: rule.postprocess || 'sentenceCase',
|
||||||
|
})}
|
||||||
</Table.Th>
|
</Table.Th>
|
||||||
<Table.Td>{value}</Table.Td>
|
<Table.Td>{value}</Table.Td>
|
||||||
</Table.Tr>
|
</Table.Tr>
|
||||||
@@ -135,12 +139,12 @@ const BoolField = (key: boolean) =>
|
|||||||
|
|
||||||
const AlbumPropertyMapping: ItemDetailRow<Album>[] = [
|
const AlbumPropertyMapping: ItemDetailRow<Album>[] = [
|
||||||
{ key: 'name', label: 'common.title' },
|
{ key: 'name', label: 'common.title' },
|
||||||
{ label: 'entity.albumArtist_one', render: (item) => formatArtists(item.albumArtists) },
|
{ count: 1, label: 'entity.albumArtist', render: (item) => formatArtists(item.albumArtists) },
|
||||||
{
|
{
|
||||||
label: 'common.releaseType',
|
label: 'common.releaseType',
|
||||||
render: (item, t) => normalizeReleaseTypes(item.releaseTypes, t).join(SEPARATOR_STRING),
|
render: (item, t) => normalizeReleaseTypes(item.releaseTypes, t).join(SEPARATOR_STRING),
|
||||||
},
|
},
|
||||||
{ label: 'entity.genre_other', render: FormatGenre },
|
{ count: 2, label: 'entity.genre', render: FormatGenre },
|
||||||
{
|
{
|
||||||
label: 'common.duration',
|
label: 'common.duration',
|
||||||
render: (album) => album.duration && formatDurationString(album.duration),
|
render: (album) => album.duration && formatDurationString(album.duration),
|
||||||
@@ -198,7 +202,7 @@ const AlbumPropertyMapping: ItemDetailRow<Album>[] = [
|
|||||||
|
|
||||||
const AlbumArtistPropertyMapping: ItemDetailRow<AlbumArtist>[] = [
|
const AlbumArtistPropertyMapping: ItemDetailRow<AlbumArtist>[] = [
|
||||||
{ key: 'name', label: 'common.name' },
|
{ key: 'name', label: 'common.name' },
|
||||||
{ label: 'entity.genre_other', render: FormatGenre },
|
{ count: 2, label: 'entity.genre', render: FormatGenre },
|
||||||
{
|
{
|
||||||
label: 'common.duration',
|
label: 'common.duration',
|
||||||
render: (artist) => artist.duration && formatDurationString(artist.duration),
|
render: (artist) => artist.duration && formatDurationString(artist.duration),
|
||||||
@@ -243,7 +247,7 @@ const AlbumArtistPropertyMapping: ItemDetailRow<AlbumArtist>[] = [
|
|||||||
const PlaylistPropertyMapping: ItemDetailRow<Playlist>[] = [
|
const PlaylistPropertyMapping: ItemDetailRow<Playlist>[] = [
|
||||||
{ key: 'name', label: 'common.title' },
|
{ key: 'name', label: 'common.title' },
|
||||||
{ key: 'description', label: 'common.description' },
|
{ key: 'description', label: 'common.description' },
|
||||||
{ label: 'entity.genre_other', render: FormatGenre },
|
{ count: 2, label: 'entity.genre', render: FormatGenre },
|
||||||
{
|
{
|
||||||
label: 'common.duration',
|
label: 'common.duration',
|
||||||
render: (playlist) => playlist.duration && formatDurationString(playlist.duration),
|
render: (playlist) => playlist.duration && formatDurationString(playlist.duration),
|
||||||
@@ -266,11 +270,17 @@ const PlaylistPropertyMapping: ItemDetailRow<Playlist>[] = [
|
|||||||
const SongPropertyMapping: ItemDetailRow<Song>[] = [
|
const SongPropertyMapping: ItemDetailRow<Song>[] = [
|
||||||
{ key: 'name', label: 'common.title' },
|
{ key: 'name', label: 'common.title' },
|
||||||
{ key: 'path', label: 'common.path', render: SongPath },
|
{ key: 'path', label: 'common.path', render: SongPath },
|
||||||
{ label: 'entity.albumArtist_one', render: (item) => formatArtists(item.albumArtists) },
|
{ count: 1, label: 'entity.albumArtist', render: (item) => formatArtists(item.albumArtists) },
|
||||||
{ key: 'artists', label: 'entity.artist_other', render: (item) => formatArtists(item.artists) },
|
|
||||||
{
|
{
|
||||||
|
count: 2,
|
||||||
|
key: 'artists',
|
||||||
|
label: 'entity.artist',
|
||||||
|
render: (item) => formatArtists(item.artists),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
count: 1,
|
||||||
key: 'album',
|
key: 'album',
|
||||||
label: 'entity.album_one',
|
label: 'entity.album',
|
||||||
render: (song) =>
|
render: (song) =>
|
||||||
song.albumId &&
|
song.albumId &&
|
||||||
song.album && (
|
song.album && (
|
||||||
@@ -304,7 +314,7 @@ const SongPropertyMapping: ItemDetailRow<Song>[] = [
|
|||||||
? t('common.clean', { postProcess: 'sentenceCase' })
|
? t('common.clean', { postProcess: 'sentenceCase' })
|
||||||
: null,
|
: null,
|
||||||
},
|
},
|
||||||
{ label: 'entity.genre_other', render: FormatGenre },
|
{ count: 2, label: 'entity.genre', render: FormatGenre },
|
||||||
{
|
{
|
||||||
label: 'common.duration',
|
label: 'common.duration',
|
||||||
render: (song) => formatDurationString(song.duration),
|
render: (song) => formatDurationString(song.duration),
|
||||||
@@ -314,7 +324,7 @@ const SongPropertyMapping: ItemDetailRow<Song>[] = [
|
|||||||
{ key: 'bitRate', label: 'common.bitrate', render: (song) => `${song.bitRate} kbps` },
|
{ key: 'bitRate', label: 'common.bitrate', render: (song) => `${song.bitRate} kbps` },
|
||||||
{ key: 'sampleRate', label: 'common.sampleRate' },
|
{ key: 'sampleRate', label: 'common.sampleRate' },
|
||||||
{ key: 'bitDepth', label: 'common.bitDepth' },
|
{ key: 'bitDepth', label: 'common.bitDepth' },
|
||||||
{ key: 'channels', label: 'common.channel_other' },
|
{ count: 2, key: 'channels', label: 'common.channel' },
|
||||||
{ key: 'size', label: 'common.size', render: (song) => formatSizeString(song.size) },
|
{ key: 'size', label: 'common.size', render: (song) => formatSizeString(song.size) },
|
||||||
{
|
{
|
||||||
label: 'common.favorite',
|
label: 'common.favorite',
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const openLyricsSettingsModal = (settingsKey: string = 'default') => {
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
title: i18n.t('common.setting_other', { postProcess: 'titleCase' }),
|
title: i18n.t('common.setting', { count: 2, postProcess: 'titleCase' }),
|
||||||
transitionProps: {
|
transitionProps: {
|
||||||
transition: 'pop',
|
transition: 'pop',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ export const PlayerConfig = () => {
|
|||||||
size="sm"
|
size="sm"
|
||||||
stopsPropagation
|
stopsPropagation
|
||||||
tooltip={{
|
tooltip={{
|
||||||
label: t('common.setting_other', { postProcess: 'titleCase' }),
|
label: t('common.setting', { count: 2, postProcess: 'titleCase' }),
|
||||||
openDelay: 0,
|
openDelay: 0,
|
||||||
}}
|
}}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const openVisualizerSettingsModal = () => {
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
title: i18n.t('common.setting_other', { postProcess: 'titleCase' }),
|
title: i18n.t('common.setting', { count: 2, postProcess: 'titleCase' }),
|
||||||
transitionProps: {
|
transitionProps: {
|
||||||
transition: 'pop',
|
transition: 'pop',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export const SearchHeader = ({ navigationId }: SearchHeaderProps) => {
|
|||||||
}}
|
}}
|
||||||
variant={itemType === LibraryItem.SONG ? 'filled' : 'default'}
|
variant={itemType === LibraryItem.SONG ? 'filled' : 'default'}
|
||||||
>
|
>
|
||||||
{t('entity.track_other', { postProcess: 'sentenceCase' })}
|
{t('entity.track', { count: 2, postProcess: 'sentenceCase' })}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
component={Link}
|
component={Link}
|
||||||
@@ -97,7 +97,7 @@ export const SearchHeader = ({ navigationId }: SearchHeaderProps) => {
|
|||||||
}}
|
}}
|
||||||
variant={itemType === LibraryItem.ALBUM ? 'filled' : 'default'}
|
variant={itemType === LibraryItem.ALBUM ? 'filled' : 'default'}
|
||||||
>
|
>
|
||||||
{t('entity.album_other', { postProcess: 'sentenceCase' })}
|
{t('entity.album', { count: 2, postProcess: 'sentenceCase' })}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
component={Link}
|
component={Link}
|
||||||
@@ -113,7 +113,7 @@ export const SearchHeader = ({ navigationId }: SearchHeaderProps) => {
|
|||||||
}}
|
}}
|
||||||
variant={itemType === LibraryItem.ALBUM_ARTIST ? 'filled' : 'default'}
|
variant={itemType === LibraryItem.ALBUM_ARTIST ? 'filled' : 'default'}
|
||||||
>
|
>
|
||||||
{t('entity.artist_other', { postProcess: 'sentenceCase' })}
|
{t('entity.artist', { count: 2, postProcess: 'sentenceCase' })}
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
<ListConfigMenu {...listConfigMenuProps[itemType]} />
|
<ListConfigMenu {...listConfigMenuProps[itemType]} />
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ export const SongListHeaderFilters = ({ toggleGenreTarget }: { toggleGenreTarget
|
|||||||
|
|
||||||
const choice = useMemo(() => {
|
const choice = useMemo(() => {
|
||||||
return target === GenreTarget.ALBUM
|
return target === GenreTarget.ALBUM
|
||||||
? t('entity.album_other', { postProcess: 'titleCase' })
|
? t('entity.album', { count: 2, postProcess: 'titleCase' })
|
||||||
: t('entity.track_other', { postProcess: 'titleCase' });
|
: t('entity.track', { count: 2, postProcess: 'titleCase' });
|
||||||
}, [target, t]);
|
}, [target, t]);
|
||||||
|
|
||||||
const hasActiveFilters = useMemo(() => {
|
const hasActiveFilters = useMemo(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user