Add Portuguese translation (incomplete)
This commit is contained in:
Generated
+5
@@ -13127,6 +13127,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-3.2.0.tgz",
|
||||||
"integrity": "sha512-/XmwYWoQoB4MBkkzBCbg/ykCuRGjHQOHLk2ik6n1aM10AWHxiiJNyRw2aoLzH7Vc5rcp4BBJQCuhT+DgfYIJ2Q=="
|
"integrity": "sha512-/XmwYWoQoB4MBkkzBCbg/ykCuRGjHQOHLk2ik6n1aM10AWHxiiJNyRw2aoLzH7Vc5rcp4BBJQCuhT+DgfYIJ2Q=="
|
||||||
},
|
},
|
||||||
|
"ra-language-portuguese": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ra-language-portuguese/-/ra-language-portuguese-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-9PAxgrisjmDOTRefjCe2y2ruYQw/iqXnXgUt09vOYUcjY4J0ctabJ4+joGI0jV/x9icF9c7Pui2USc5QDRTktQ=="
|
||||||
|
},
|
||||||
"ra-ui-materialui": {
|
"ra-ui-materialui": {
|
||||||
"version": "3.3.3",
|
"version": "3.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/ra-ui-materialui/-/ra-ui-materialui-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/ra-ui-materialui/-/ra-ui-materialui-3.3.3.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"md5-hex": "^3.0.1",
|
"md5-hex": "^3.0.1",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"ra-data-json-server": "^3.3.3",
|
"ra-data-json-server": "^3.3.3",
|
||||||
|
"ra-language-portuguese": "^1.6.0",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-admin": "^3.3.3",
|
"react-admin": "^3.3.3",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import {
|
|||||||
NumberInput,
|
NumberInput,
|
||||||
ReferenceInput,
|
ReferenceInput,
|
||||||
SearchInput,
|
SearchInput,
|
||||||
Pagination
|
Pagination,
|
||||||
|
useTranslate
|
||||||
} from 'react-admin'
|
} from 'react-admin'
|
||||||
import { Title } from '../common'
|
import { Title } from '../common'
|
||||||
import { withWidth } from '@material-ui/core'
|
import { withWidth } from '@material-ui/core'
|
||||||
@@ -17,10 +18,13 @@ import AlbumListView from './AlbumListView'
|
|||||||
import AlbumGridView from './AlbumGridView'
|
import AlbumGridView from './AlbumGridView'
|
||||||
import { ALBUM_MODE_LIST } from './albumState'
|
import { ALBUM_MODE_LIST } from './albumState'
|
||||||
|
|
||||||
const AlbumFilter = (props) => (
|
const AlbumFilter = (props) => {
|
||||||
|
const translate = useTranslate()
|
||||||
|
return (
|
||||||
<Filter {...props}>
|
<Filter {...props}>
|
||||||
<SearchInput source="name" alwaysOn />
|
<SearchInput source="name" alwaysOn />
|
||||||
<ReferenceInput
|
<ReferenceInput
|
||||||
|
label={translate('resources.album.fields.artist')}
|
||||||
source="artist_id"
|
source="artist_id"
|
||||||
reference="artist"
|
reference="artist"
|
||||||
sort={{ field: 'name', order: 'ASC' }}
|
sort={{ field: 'name', order: 'ASC' }}
|
||||||
@@ -32,6 +36,7 @@ const AlbumFilter = (props) => (
|
|||||||
<NumberInput source="year" />
|
<NumberInput source="year" />
|
||||||
</Filter>
|
</Filter>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const getPerPage = (width) => {
|
const getPerPage = (width) => {
|
||||||
if (width === 'xs') return 12
|
if (width === 'xs') return 12
|
||||||
|
|||||||
@@ -27,12 +27,30 @@ const Player = () => {
|
|||||||
glassBg: false,
|
glassBg: false,
|
||||||
showThemeSwitch: false,
|
showThemeSwitch: false,
|
||||||
showMediaSession: true,
|
showMediaSession: true,
|
||||||
panelTitle: translate('player.panelTitle'),
|
|
||||||
defaultPosition: {
|
defaultPosition: {
|
||||||
top: 300,
|
top: 300,
|
||||||
left: 120
|
left: 120
|
||||||
},
|
},
|
||||||
locale: {
|
locale: {
|
||||||
|
playListsText: translate('player.playListsText'),
|
||||||
|
openText: translate('player.openText'),
|
||||||
|
closeText: translate('player.closeText'),
|
||||||
|
notContentText: translate('player.notContentText'),
|
||||||
|
clickToPlayText: translate('player.clickToPlayText'),
|
||||||
|
clickToPauseText: translate('player.clickToPauseText'),
|
||||||
|
nextTrackText: translate('player.nextTrackText'),
|
||||||
|
previousTrackText: translate('player.previousTrackText'),
|
||||||
|
reloadText: translate('player.reloadText'),
|
||||||
|
volumeText: translate('player.volumeText'),
|
||||||
|
toggleLyricText: translate('player.toggleLyricText'),
|
||||||
|
toggleMiniModeText: translate('player.toggleMiniModeText'),
|
||||||
|
destroyText: translate('player.destroyText'),
|
||||||
|
downloadText: translate('player.downloadText'),
|
||||||
|
removeAudioListsText: translate('player.removeAudioListsText'),
|
||||||
|
controllerTitle: translate('player.controllerTitle'),
|
||||||
|
clickToDeleteText: (name) =>
|
||||||
|
translate('player.clickToDeleteText', { name }),
|
||||||
|
emptyLyricText: translate('player.emptyLyricText'),
|
||||||
playModeText: {
|
playModeText: {
|
||||||
order: translate('player.playModeText.order'),
|
order: translate('player.playModeText.order'),
|
||||||
orderLoop: translate('player.playModeText.orderLoop'),
|
orderLoop: translate('player.playModeText.orderLoop'),
|
||||||
|
|||||||
+25
-2
@@ -2,6 +2,7 @@ import deepmerge from 'deepmerge'
|
|||||||
import englishMessages from 'ra-language-english'
|
import englishMessages from 'ra-language-english'
|
||||||
|
|
||||||
export default deepmerge(englishMessages, {
|
export default deepmerge(englishMessages, {
|
||||||
|
languageName: 'English',
|
||||||
resources: {
|
resources: {
|
||||||
song: {
|
song: {
|
||||||
name: 'Song |||| Songs',
|
name: 'Song |||| Songs',
|
||||||
@@ -45,12 +46,34 @@ export default deepmerge(englishMessages, {
|
|||||||
menu: {
|
menu: {
|
||||||
library: 'Library',
|
library: 'Library',
|
||||||
settings: 'Settings',
|
settings: 'Settings',
|
||||||
personal: 'Personal',
|
|
||||||
version: 'Version %{version}',
|
version: 'Version %{version}',
|
||||||
|
theme: 'Theme',
|
||||||
|
personal: {
|
||||||
|
name: 'Personal',
|
||||||
|
options: {
|
||||||
theme: 'Theme'
|
theme: 'Theme'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
player: {
|
player: {
|
||||||
panelTitle: 'Play Queue',
|
playListsText: 'Play Queue',
|
||||||
|
openText: 'Open',
|
||||||
|
closeText: 'Close',
|
||||||
|
notContentText: 'No music',
|
||||||
|
clickToPlayText: 'Click to play',
|
||||||
|
clickToPauseText: 'Click to pause',
|
||||||
|
nextTrackText: 'Next track',
|
||||||
|
previousTrackText: 'Previous track',
|
||||||
|
reloadText: 'Reload',
|
||||||
|
volumeText: 'Volume',
|
||||||
|
toggleLyricText: 'Toggle lyric',
|
||||||
|
toggleMiniModeText: 'Minimize',
|
||||||
|
destroyText: 'Destroy',
|
||||||
|
downloadText: 'Download',
|
||||||
|
removeAudioListsText: 'Delete audio lists',
|
||||||
|
controllerTitle: '',
|
||||||
|
clickToDeleteText: `Click to delete %{name}`,
|
||||||
|
emptyLyricText: 'No lyric',
|
||||||
playModeText: {
|
playModeText: {
|
||||||
order: 'In order',
|
order: 'In order',
|
||||||
orderLoop: 'Repeat',
|
orderLoop: 'Repeat',
|
||||||
|
|||||||
+11
-1
@@ -1,3 +1,13 @@
|
|||||||
import en from './en'
|
import en from './en'
|
||||||
|
import pt from './pt'
|
||||||
|
|
||||||
export default { en }
|
// When adding a new translation, import it above and add it to the list bellow
|
||||||
|
|
||||||
|
const allLanguages = { en, pt }
|
||||||
|
|
||||||
|
// "Hack" to make "albumSongs" resource use the same translations as "song"
|
||||||
|
Object.keys(allLanguages).forEach(
|
||||||
|
(k) => (allLanguages[k].resources.albumSong = allLanguages[k].resources.song)
|
||||||
|
)
|
||||||
|
|
||||||
|
export default allLanguages
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import deepmerge from 'deepmerge'
|
||||||
|
import en from './en'
|
||||||
|
import portugueseMessages from 'ra-language-portuguese'
|
||||||
|
|
||||||
|
export default deepmerge.all([
|
||||||
|
en,
|
||||||
|
portugueseMessages,
|
||||||
|
{
|
||||||
|
languageName: 'Português',
|
||||||
|
resources: {
|
||||||
|
song: {
|
||||||
|
name: 'Música |||| Músicas',
|
||||||
|
fields: {
|
||||||
|
title: 'Título',
|
||||||
|
artist: 'Artista',
|
||||||
|
album: 'Álbum',
|
||||||
|
path: 'Caminho',
|
||||||
|
genre: 'Gênero',
|
||||||
|
compilation: 'Coletânea',
|
||||||
|
duration: 'Duração',
|
||||||
|
year: 'Ano',
|
||||||
|
trackNumber: '#'
|
||||||
|
},
|
||||||
|
bulk: {
|
||||||
|
addToQueue: 'Play Later'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
album: {
|
||||||
|
name: 'Álbum |||| Álbuns',
|
||||||
|
fields: {
|
||||||
|
name: 'Nome',
|
||||||
|
artist: 'Artista',
|
||||||
|
songCount: 'Songs',
|
||||||
|
genre: 'Gênero',
|
||||||
|
playCount: 'Plays',
|
||||||
|
compilation: 'Coletânea',
|
||||||
|
duration: 'Duração',
|
||||||
|
year: 'Ano'
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
playAll: 'Play',
|
||||||
|
playNext: 'Play Next',
|
||||||
|
addToQueue: 'Play Later',
|
||||||
|
shuffle: 'Shuffle'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
artist: {
|
||||||
|
name: 'Artista |||| Artistas',
|
||||||
|
fields: {
|
||||||
|
name: 'Nome'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
name: 'Usuário |||| Usuários',
|
||||||
|
fields: {
|
||||||
|
name: 'Nome'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transcoding: {
|
||||||
|
name: 'Conversão |||| Conversões',
|
||||||
|
fields: {
|
||||||
|
name: 'Nome'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
player: {
|
||||||
|
name: 'Tocador |||| Tocadores',
|
||||||
|
fields: {
|
||||||
|
name: 'Nome'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ra: {
|
||||||
|
auth: {
|
||||||
|
welcome1: 'Thanks for installing Navidrome!',
|
||||||
|
welcome2: 'To start, create an admin user',
|
||||||
|
confirmPassword: 'Confirm Password',
|
||||||
|
buttonCreateAdmin: 'Create Admin'
|
||||||
|
},
|
||||||
|
validation: {
|
||||||
|
invalidChars: 'Please only use letter and numbers',
|
||||||
|
passwordDoesNotMatch: 'Password does not match'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
menu: {
|
||||||
|
library: 'Biblioteca',
|
||||||
|
settings: 'Configurações',
|
||||||
|
version: 'Versão %{version}',
|
||||||
|
personal: {
|
||||||
|
name: 'Pessoal',
|
||||||
|
options: {
|
||||||
|
theme: 'Tema'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
player: {
|
||||||
|
playListsText: 'Fila de Execução',
|
||||||
|
openText: 'Abrir',
|
||||||
|
closeText: 'Fechar',
|
||||||
|
clickToPlayText: 'Clique para tocar',
|
||||||
|
clickToPauseText: 'Clique para pausar',
|
||||||
|
nextTrackText: 'Próxima faixa',
|
||||||
|
previousTrackText: 'Faixa anterior',
|
||||||
|
clickToDeleteText: `Clique para remover %{name}`,
|
||||||
|
playModeText: {
|
||||||
|
order: 'Em ordem',
|
||||||
|
orderLoop: 'Repetir tudo',
|
||||||
|
singleLoop: 'Repetir',
|
||||||
|
shufflePlay: 'Aleatório'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
@@ -16,7 +16,7 @@ const PersonalMenu = forwardRef(({ onClick, sidebarIsOpen, dense }, ref) => {
|
|||||||
<MenuItemLink
|
<MenuItemLink
|
||||||
ref={ref}
|
ref={ref}
|
||||||
to="/personal"
|
to="/personal"
|
||||||
primaryText={translate('menu.personal')}
|
primaryText={translate('menu.personal.name')}
|
||||||
leftIcon={<TuneIcon />}
|
leftIcon={<TuneIcon />}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className={classes.menuItem}
|
className={classes.menuItem}
|
||||||
|
|||||||
@@ -21,10 +21,11 @@ const Personal = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={classes.root}>
|
<Card className={classes.root}>
|
||||||
<Title title={'Navidrome - ' + translate('menu.personal')} />
|
<Title title={'Navidrome - ' + translate('menu.personal.name')} />
|
||||||
<SimpleForm toolbar={null}>
|
<SimpleForm toolbar={null}>
|
||||||
<SelectInput
|
<SelectInput
|
||||||
source="theme"
|
source="theme"
|
||||||
|
label={translate('menu.personal.options.theme')}
|
||||||
defaultValue={currentTheme}
|
defaultValue={currentTheme}
|
||||||
choices={themeChoices}
|
choices={themeChoices}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
|
|||||||
+10
-2
@@ -6,7 +6,8 @@ import {
|
|||||||
List,
|
List,
|
||||||
NumberField,
|
NumberField,
|
||||||
SearchInput,
|
SearchInput,
|
||||||
TextField
|
TextField,
|
||||||
|
useTranslate
|
||||||
} from 'react-admin'
|
} from 'react-admin'
|
||||||
import { useMediaQuery } from '@material-ui/core'
|
import { useMediaQuery } from '@material-ui/core'
|
||||||
import {
|
import {
|
||||||
@@ -30,6 +31,7 @@ const SongFilter = (props) => (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const SongList = (props) => {
|
const SongList = (props) => {
|
||||||
|
const translate = useTranslate()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
|
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
|
||||||
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))
|
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))
|
||||||
@@ -63,7 +65,13 @@ const SongList = (props) => {
|
|||||||
rowClick={(id, basePath, record) => dispatch(setTrack(record))}
|
rowClick={(id, basePath, record) => dispatch(setTrack(record))}
|
||||||
>
|
>
|
||||||
<TextField source="title" />
|
<TextField source="title" />
|
||||||
{isDesktop && <AlbumLinkField source="albumId" sortBy="album" />}
|
{isDesktop && (
|
||||||
|
<AlbumLinkField
|
||||||
|
source="albumId"
|
||||||
|
label={translate('resources.song.fields.album')}
|
||||||
|
sortBy="album"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<TextField source="artist" />
|
<TextField source="artist" />
|
||||||
{isDesktop && <NumberField source="trackNumber" />}
|
{isDesktop && <NumberField source="trackNumber" />}
|
||||||
{isDesktop && <NumberField source="playCount" />}
|
{isDesktop && <NumberField source="playCount" />}
|
||||||
|
|||||||
Reference in New Issue
Block a user