Merge branch 'main' into router-implementation

This commit is contained in:
Roberto Tonino 2020-08-22 21:11:22 +02:00
commit a53204668b
44 changed files with 2773 additions and 1141 deletions

1
.gitignore vendored
View File

@ -3,7 +3,6 @@ __pycache__
.DS_Store .DS_Store
node_modules node_modules
jsconfig.json
# pyinstaller build dirs # pyinstaller build dirs
/dist /dist

View File

@ -4,34 +4,34 @@ This is just the WebUI for deemix, it should be used with deemix-pyweb or someth
## What's left to do? ## What's left to do?
- Use Vue as much as possible - [ ] Use Vue app-wide
- First step: rewrite the app in Single File Components way ✅ - [X] First step: rewrite the app in Single File Components way
- Second step: Implement custom contextmenu - [ ] Second step: Implement routing for the whole app using Vue Router ⚒
- Third step: Implement routing for the whole app using Vue Router - [ ] Third step: Remove jQuery
- Fourth step: Remove jQuery - [ ] Implement custom contextmenu ⚒
- Make i18n async (https://kazupon.github.io/vue-i18n/guide/lazy-loading.html) - [X] Copy and paste functions
- [X] Copy Link where possible
- [X] Download Quality
- [X] Copy Image URL where possible
- [ ] Resolve cut/copy/paste compatibility issues
- [ ] Make i18n async (https://kazupon.github.io/vue-i18n/guide/lazy-loading.html)
- Use ES2020 async imports, if possible - Use ES2020 async imports, if possible
- Make the UI look coherent - [ ] Make the UI look coherent
- Style buttons - [ ] Style buttons
- Style text inputs - [ ] Style text inputs
- Style checkboxes - [ ] Style checkboxes
- Search tab - [ ] Search tab
- Better placeholer before search - [ ] Better placeholer before search
- Link Analyzer - [ ] Link Analyzer
- Better placeholer before analyzing and error feedback - [ ] Better placeholer before analyzing and error feedback
- Settings tab - [ ] Settings tab
- Maybe tabbing the section for easy navigation - [ ] Variable selector near template inputs
- Could use a carousel, but it's not worth adding a new dep - Maybe tabbing the section for easy navigation
- Variable selector near template inputs - Could use a carousel, but it's not worth adding a new dep
- Add Custom Context menu to objects - [ ] Block selection where it's not needed (keep only titles artists albums labels and useful data)
- Copy Link where possible
- Copy Image URL where possible
- Context menu for pywebview (Context menu is blocked in pywebview)
- Copy and paste functions
- Block selection where it's not needed (keep only titles artists albums labels and useful data)
- There's a SASS mixin for this. Need to use it in the proper classes - There's a SASS mixin for this. Need to use it in the proper classes
- Better feedback for socket.io possible errors - [ ] Better feedback for socket.io possible errors
- Remove images size limit and add warning if > 1200 - [X] Remove images size limit and add warning if > 1200
- ? - ?
# License # License

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,8 @@ function mountApp() {
function initClient() { function initClient() {
window.clientMode = true window.clientMode = true
document.querySelector(`#open_downloads_folder`).classList.remove('hide') document.querySelector(`#open_downloads_folder`).classList.remove('hide')
document.querySelector(`#select_downloads_folder`).classList.remove('hide')
document.querySelector(`#settings_btn_applogin`).classList.remove('hide')
} }
document.addEventListener('DOMContentLoaded', startApp) document.addEventListener('DOMContentLoaded', startApp)
@ -120,6 +122,10 @@ socket.on('logged_out', function() {
document.getElementById('home_not_logged_in').classList.remove('hide') document.getElementById('home_not_logged_in').classList.remove('hide')
}) })
socket.on('restoringQueue', function() {
toast(i18n.t('toasts.restoringQueue'), 'loading', false, 'restoring_queue')
})
socket.on('cancellingCurrentItem', function(uuid) { socket.on('cancellingCurrentItem', function(uuid) {
toast(i18n.t('toasts.cancellingCurrentItem'), 'loading', false, 'cancelling_' + uuid) toast(i18n.t('toasts.cancellingCurrentItem'), 'loading', false, 'cancelling_' + uuid)
}) })
@ -156,3 +162,7 @@ socket.on('queueError', function(queueItem) {
socket.on('alreadyInQueue', function(data) { socket.on('alreadyInQueue', function(data) {
toast(i18n.t('toasts.alreadyInQueue', [data.title]), 'playlist_add_check') toast(i18n.t('toasts.alreadyInQueue', [data.title]), 'playlist_add_check')
}) })
socket.on('loginNeededToDownload', function(data) {
toast(i18n.t('toasts.loginNeededToDownload'), 'report')
})

102
src/assets/ar.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -1,3 +0,0 @@
<svg viewBox="0 0 65 65" xmlns="http://www.w3.org/2000/svg">
<path d="M37.4984 36.7246C37.7727 37.3718 37.822 38.0823 37.6813 38.9194C37.4984 39.8901 37.0763 40.6499 36.408 41.2408C35.7327 41.8106 35.0011 42.1552 34.1922 42.2326C33.3762 42.31 32.3843 42.2326 31.2166 42.0216L29.1977 41.6277C28.5294 41.494 28.1284 41.3955 27.9807 41.29C27.84 41.1915 27.7626 41.0508 27.7274 40.8539C27.7134 40.7061 27.7696 40.1856 27.9103 39.3485L29.0288 33.3691L32.6094 34.0304C34.1781 34.3329 35.3177 34.6987 36.0211 35.1207C36.7316 35.5428 37.217 36.0915 37.4984 36.7246ZM37.6883 24.1539C37.0552 23.8022 35.8453 23.4645 34.0726 23.1339L31.0477 22.5641L29.7815 29.2962L32.8134 29.8659C34.3962 30.1544 35.592 30.2458 36.401 30.1192C37.21 29.9855 37.8431 29.6971 38.3355 29.2399C38.8068 28.7967 39.1234 28.1988 39.25 27.4953C39.3907 26.7637 39.3203 26.1236 39.053 25.5327C38.7998 24.9629 38.3496 24.4916 37.6883 24.1539ZM64.5179 32.518C64.5179 50.2027 50.1886 64.518 32.5109 64.518C14.8402 64.518 0.517944 50.2027 0.517944 32.518C0.517944 14.8332 14.8402 0.51796 32.5109 0.51796C50.1886 0.51796 64.5179 14.8332 64.5179 32.518ZM45.6866 24.0625C45.1449 22.8807 44.2304 21.8818 42.9712 21.0587C42.4929 20.7351 41.8809 20.4538 41.2126 20.1935L42.1201 15.3326L37.4491 14.4533L36.5909 18.9976L33.5872 18.4349L34.4454 13.8906L29.7675 13.0113L28.9092 17.5626L21.7692 16.226L21.0587 20.0458L22.1491 20.2498C22.8807 20.3764 23.359 20.5382 23.5841 20.7211C23.8233 20.8899 23.964 21.108 24.0273 21.3542C24.0906 21.6004 24.0484 22.128 23.8936 22.9581L21.0095 38.3496C20.8618 39.1515 20.7211 39.665 20.5663 39.869C20.4115 40.073 20.2005 40.2278 19.9191 40.3052C19.6378 40.3825 19.1383 40.3544 18.4137 40.1996L17.3164 40.0168L16.6059 43.8224L23.7389 45.1449L22.8947 49.6892L27.5727 50.5685L28.4168 46.0242L31.0759 46.5166C31.1955 46.5448 31.301 46.5518 31.4206 46.5799L30.5764 51.1242L35.2473 51.9895L36.1759 47.0724C36.9849 47.0583 37.7094 46.988 38.3496 46.8824C40.0871 46.5377 41.5081 45.8272 42.6265 44.751C43.738 43.6958 44.4344 42.4296 44.7017 40.9594C44.9339 39.7213 44.8494 38.5536 44.4555 37.4702C44.0545 36.3588 43.4144 35.4373 42.5281 34.6916C41.9231 34.1711 40.9945 33.6224 39.7705 33.0596C41.0508 32.8697 42.113 32.5391 42.9642 32.0396C43.8224 31.5472 44.5188 30.9282 45.0534 30.1755C45.5951 29.4298 45.9609 28.5927 46.1227 27.6852C46.3759 26.4894 46.2282 25.2513 45.6866 24.0625Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -7,6 +7,8 @@
<TheTrackPreview /> <TheTrackPreview />
<TheQualityModal /> <TheQualityModal />
<TheContextMenu />
</div> </div>
</template> </template>
@ -16,6 +18,7 @@ import TheMainContent from '@components/TheMainContent.vue'
import TheTrackPreview from '@components/TheTrackPreview.vue' import TheTrackPreview from '@components/TheTrackPreview.vue'
import TheQualityModal from '@components/TheQualityModal.vue' import TheQualityModal from '@components/TheQualityModal.vue'
import BaseLoadingPlaceholder from '@components/BaseLoadingPlaceholder.vue' import BaseLoadingPlaceholder from '@components/BaseLoadingPlaceholder.vue'
import TheContextMenu from '@components/TheContextMenu.vue'
export default { export default {
components: { components: {
@ -23,10 +26,8 @@ export default {
TheMainContent, TheMainContent,
TheTrackPreview, TheTrackPreview,
TheQualityModal, TheQualityModal,
BaseLoadingPlaceholder BaseLoadingPlaceholder,
TheContextMenu
} }
} }
</script> </script>
<style>
</style>

View File

@ -8,14 +8,7 @@
}" }"
> >
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
<div <div role="button" aria-label="download" @click.stop="addToQueue" :data-link="link" class="fab right">
role="button"
aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue"
:data-link="link"
class="fab right"
>
<i class="material-icons" :title="$t('globals.download_hint')">get_app</i> <i class="material-icons" :title="$t('globals.download_hint')">get_app</i>
</div> </div>
</header> </header>
@ -69,12 +62,8 @@
</i> </i>
</td> </td>
<td>{{ release.release_date }}</td> <td>{{ release.release_date }}</td>
<td <td>{{ release.nb_song }}</td>
@click.stop="addToQueue" <td @click.stop="addToQueue" :data-link="release.link" class="clickable">
@contextmenu.prevent="openQualityModal"
:data-link="release.link"
class="clickable"
>
<i class="material-icons" :title="$t('globals.download_hint')"> <i class="material-icons" :title="$t('globals.download_hint')">
file_download file_download
</i> </i>
@ -129,9 +118,6 @@ export default {
e.stopPropagation() e.stopPropagation()
Downloads.sendAddToQueue(e.currentTarget.dataset.link) Downloads.sendAddToQueue(e.currentTarget.dataset.link)
}, },
openQualityModal(e) {
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
},
sortBy(key) { sortBy(key) {
if (key == this.sortKey) { if (key == this.sortKey) {
this.sortOrder = this.sortOrder == 'asc' ? 'desc' : 'asc' this.sortOrder = this.sortOrder == 'asc' ? 'desc' : 'asc'
@ -172,6 +158,7 @@ export default {
this.head = [ this.head = [
{ title: this.$tc('globals.listTabs.title', 1), sortKey: 'title' }, { title: this.$tc('globals.listTabs.title', 1), sortKey: 'title' },
{ title: this.$t('globals.listTabs.releaseDate'), sortKey: 'release_date' }, { title: this.$t('globals.listTabs.releaseDate'), sortKey: 'release_date' },
{ title: this.$tc('globals.listTabs.track', 2), sortKey: 'nb_song' },
{ title: '', width: '32px' } { title: '', width: '32px' }
] ]
if (isEmpty(releases)) { if (isEmpty(releases)) {
@ -183,8 +170,17 @@ export default {
}, },
computed: { computed: {
showTable() { showTable() {
if (this.body) return orderBy(this.body[this.currentTab], this.sortKey, this.sortOrder) if (this.body) {
else return [] if (this.sortKey == 'nb_song')
return orderBy(
this.body[this.currentTab],
function (o) {
return new Number(o.nb_song)
},
this.sortOrder
)
else return orderBy(this.body[this.currentTab], this.sortKey, this.sortOrder)
} else return []
} }
}, },
mounted() { mounted() {

View File

@ -82,10 +82,6 @@
<strong>PayPal:</strong> <strong>PayPal:</strong>
<a href="https://paypal.me/RemixDev" target="_blank">PayPal.me/RemixDev</a> <a href="https://paypal.me/RemixDev" target="_blank">PayPal.me/RemixDev</a>
</li> </li>
<li>
<i class="bitcoin" v-html="bitcoin" />
<strong>Bitcoin:</strong> 1sdNymSJrMBWyHM4u2m9uco5nv6uV4Qs1
</li>
<li> <li>
<i class="ethereum" v-html="ethereum" /> <i class="ethereum" v-html="ethereum" />
<strong>Ethereum:</strong> 0x1d2aa67e671485CD4062289772B662e0A6Ff976c <strong>Ethereum:</strong> 0x1d2aa67e671485CD4062289772B662e0A6Ff976c
@ -123,10 +119,6 @@ i /deep/ svg {
width: 20px; width: 20px;
} }
.bitcoin /deep/ svg {
fill: #ff9900;
}
.ethereum /deep/ svg { .ethereum /deep/ svg {
fill: var(--foreground); fill: var(--foreground);
} }
@ -200,14 +192,12 @@ ul {
</style> </style>
<script> <script>
import paypal from '@/assets/paypal.svg' import paypal from '@/assets/paypal.svg'
import bitcoin from '@/assets/bitcoin.svg'
import ethereum from '@/assets/ethereum.svg' import ethereum from '@/assets/ethereum.svg'
export default { export default {
data: () => ({ data: () => ({
paypal, paypal,
ethereum, ethereum
bitcoin
}), }),
mounted() { mounted() {
console.log('about mounted') console.log('about mounted')

View File

@ -36,11 +36,7 @@
</div> </div>
<div v-else id="charts_table"> <div v-else id="charts_table">
<button @click="changeCountry">{{ $t('charts.changeCountry') }}</button> <button @click="changeCountry">{{ $t('charts.changeCountry') }}</button>
<button <button @click.stop="addToQueue" :data-link="'https://www.deezer.com/playlist/' + id">
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue"
:data-link="'https://www.deezer.com/playlist/' + id"
>
{{ $t('charts.download') }} {{ $t('charts.download') }}
</button> </button>
<table class="table table--charts"> <table class="table table--charts">
@ -94,7 +90,6 @@
</td> </td>
<td <td
class="table__cell--download" class="table__cell--download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="track.link" :data-link="track.link"
role="button" role="button"
@ -144,9 +139,6 @@ export default {
e.stopPropagation() e.stopPropagation()
Downloads.sendAddToQueue(e.currentTarget.dataset.link) Downloads.sendAddToQueue(e.currentTarget.dataset.link)
}, },
openQualityModal(e) {
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
},
getTrackList(event) { getTrackList(event) {
document.getElementById('content').scrollTo(0, 0) document.getElementById('content').scrollTo(0, 0)

View File

@ -0,0 +1,316 @@
<template>
<div class="context-menu" v-show="menuOpen" ref="contextMenu" :style="{ top: yPos, left: xPos }">
<button
class="menu-option"
v-for="option of sortedOptions"
:key="option.label"
v-show="option.show"
@click.prevent="option.action"
>
<span class="menu-option__text">{{ option.label }}</span>
</button>
</div>
</template>
<script>
import Downloads from '@/utils/downloads'
import downloadQualities from '@js/qualities'
import { generatePath, copyToClipboard } from '@/utils/utils'
export default {
data() {
return {
menuOpen: false,
xPos: 0,
yPos: 0,
deezerHref: '',
generalHref: '',
imgSrc: ''
}
},
computed: {
options() {
// In the action property:
// Use arrow functions to keep the Vue instance in 'this'
// Use normal functions to keep the object instance in 'this'
const options = {
cut: {
label: this.$t('globals.cut'),
show: false,
position: 1,
action: () => {
document.execCommand('Cut')
}
},
copy: {
label: this.$t('globals.copy'),
show: false,
position: 2,
action: () => {
document.execCommand('Copy')
}
},
copyLink: {
label: this.$t('globals.copyLink'),
show: false,
position: 3,
action: () => {
copyToClipboard(this.generalHref)
}
},
copyImageLink: {
label: this.$t('globals.copyImageLink'),
show: false,
position: 4,
action: () => {
copyToClipboard(this.imgSrc)
}
},
copyDeezerLink: {
label: this.$t('globals.copyDeezerLink'),
show: false,
position: 5,
action: () => {
copyToClipboard(this.deezerHref)
}
},
paste: {
label: this.$t('globals.paste'),
show: false,
position: 6,
action: () => {
// Paste does not always work
if (clipboard in navigator) {
navigator.clipboard.readText().then(text => {
document.execCommand('insertText', undefined, text)
})
} else {
document.execCommand('paste')
}
}
}
}
let nextValuePosition = Object.values(options).length + 1
downloadQualities.forEach((quality, index) => {
options[quality.objName] = {
label: `${this.$t('globals.download', [quality.label])}`,
show: false,
position: nextValuePosition + index,
action: this.tryToDownloadTrack.bind(null, quality.value)
}
})
return options
},
/**
* This computed property is used for rendering the options in the wanted order
* while keeping the options computed property an Object to make the properties
* accessible via property name (es this.options.copyLink)
*
* @return {object[]} Options in order according to position property
*/
sortedOptions() {
return Object.values(this.options).sort((first, second) => {
return first.position < second.position ? -1 : 1
})
}
},
mounted() {
document.body.addEventListener('contextmenu', this.showMenu)
document.body.addEventListener('click', this.hideMenu)
},
methods: {
showMenu(contextMenuEvent) {
// contextMenuEvent.preventDefault()
const { pageX, pageY, target: elementClicked } = contextMenuEvent
const path = generatePath(elementClicked)
let deezerLink = null
// Searching for the first element with a data-link attribute
// let deezerLink = this.searchForDataLink(...)
for (let i = 0; i < path.length; i++) {
if (path[i] == document) break
if (path[i].matches('[data-link]')) {
deezerLink = path[i].dataset.link
break
}
}
const isLink = elementClicked.matches('a')
const isImage = elementClicked.matches('img')
const hasDeezerLink = !!deezerLink
if (!isLink && !isImage && !hasDeezerLink) return
contextMenuEvent.preventDefault()
this.menuOpen = true
this.positionMenu(pageX, pageY)
if (isLink) {
// Show 'Copy Link' option
this.generalHref = elementClicked.href
this.options.copyLink.show = true
}
if (isImage) {
// Show 'Copy Image Link' option
this.imgSrc = elementClicked.src
this.options.copyImageLink.show = true
}
if (deezerLink) {
// Show 'Copy Deezer Link' option
this.deezerHref = deezerLink
this.showDeezerOptions()
}
},
hideMenu() {
if (!this.menuOpen) return
// Finish all operations before closing (may be not necessary)
this.$nextTick()
.then(() => {
this.menuOpen = false
this.options.copyLink.show = false
this.options.copyDeezerLink.show = false
this.options.copyImageLink.show = false
downloadQualities.forEach(quality => {
this.options[quality.objName].show = false
})
})
.catch(err => {
console.error(err)
})
},
positionMenu(newX, newY) {
this.xPos = `${newX}px`
this.yPos = `${newY}px`
this.$nextTick().then(() => {
const { innerHeight, innerWidth } = window
const menuXOffest = newX + this.$refs.contextMenu.getBoundingClientRect().width
const menuYOffest = newY + this.$refs.contextMenu.getBoundingClientRect().height
if (menuXOffest > innerWidth) {
const difference = menuXOffest - innerWidth + 15
this.xPos = `${newX - difference}px`
}
if (menuYOffest > innerHeight) {
const difference = menuYOffest - innerHeight + 15
this.yPos = `${newY - difference}px`
}
})
},
showDeezerOptions() {
this.options.copyDeezerLink.show = true
downloadQualities.forEach(quality => {
this.options[quality.objName].show = true
})
},
tryToDownloadTrack(qualityValue) {
Downloads.sendAddToQueue(this.deezerHref, qualityValue)
}
}
}
</script>
<style lang="scss" scoped>
.context-menu {
position: absolute;
top: 0;
left: 0;
min-width: 100px;
border-radius: 7px;
background: var(--foreground-inverted);
box-shadow: 4px 10px 18px 0px hsla(0, 0%, 0%, 0.15);
overflow: hidden;
z-index: 10000;
}
.menu-option {
display: flex;
align-items: center;
width: 100%;
height: 40px;
padding-left: 10px;
padding-right: 10px;
color: var(--foreground);
cursor: pointer;
&:hover {
background: var(--table-highlight);
filter: brightness(150%);
}
&__text {
text-transform: capitalize;
}
}
// Resetting buttons only for this component (because the style is scoped)
button {
color: var(--accent-text);
color: unset;
background-color: var(--accent-color);
background-color: unset;
min-width: unset;
position: unset;
border: unset;
border-radius: unset;
font-family: unset;
font-weight: unset;
font-size: unset;
padding: unset;
margin-right: unset;
height: unset;
text-transform: unset;
cursor: unset;
transition: unset;
&:focus {
outline: none;
}
&[disabled] {
background-color: unset;
color: unset;
opacity: unset;
}
&.selective {
background-color: unset;
color: unset;
&.active {
background-color: unset;
color: unset;
}
}
&.with_icon {
display: unset;
align-items: unset;
i {
margin-left: unset;
}
}
&:active {
background-color: unset;
transform: unset;
}
&:hover {
background: unset;
border: unset;
}
}
</style>

View File

@ -15,9 +15,7 @@
:title="$t('globals.toggle_download_tab_hint')" :title="$t('globals.toggle_download_tab_hint')"
></i> ></i>
<div id="queue_buttons"> <div id="queue_buttons">
<i id="open_downloads_folder" class="material-icons download_bar_icon hide" @click="openDownloadsFolder"> <i id="open_downloads_folder" class="material-icons download_bar_icon hide" :title="$t('globals.open_downloads_folder')" @click="openDownloadsFolder">folder_open</i>
folder_open
</i>
<i id="clean_queue" class="material-icons download_bar_icon" @click="cleanQueue" :title="$t('globals.clean_queue_hint')">clear_all</i> <i id="clean_queue" class="material-icons download_bar_icon" @click="cleanQueue" :title="$t('globals.clean_queue_hint')">clear_all</i>
<i id="cancel_queue" class="material-icons download_bar_icon" @click="cancelQueue" :title="$t('globals.cancel_queue_hint')">delete_sweep</i> <i id="cancel_queue" class="material-icons download_bar_icon" @click="cancelQueue" :title="$t('globals.cancel_queue_hint')">delete_sweep</i>
</div> </div>
@ -42,6 +40,7 @@ export default {
}), }),
mounted() { mounted() {
socket.on('startDownload', this.startDownload) socket.on('startDownload', this.startDownload)
socket.on('startConversion', this.startConversion)
socket.on('init_downloadQueue', this.initQueue) socket.on('init_downloadQueue', this.initQueue)
socket.on('addedToQueue', this.addToQueue) socket.on('addedToQueue', this.addToQueue)
socket.on('updateQueue', this.updateQueue) socket.on('updateQueue', this.updateQueue)
@ -97,26 +96,43 @@ export default {
} }
}, },
initQueue(data) { initQueue(data) {
const { queue: initQueue, queueComplete: initQueueComplete, currentItem, queueList: initQueueList } = data const { queue: initQueue, queueComplete: initQueueComplete, currentItem, queueList: initQueueList, restored } = data
if (initQueueComplete.length) { if (initQueueComplete.length) {
initQueueComplete.forEach(item => { initQueueComplete.forEach(item => {
initQueueList[item].init = true initQueueList[item].silent = true
this.addToQueue(initQueueList[item]) this.addToQueue(initQueueList[item])
}) })
} }
if (currentItem) { if (currentItem) {
initQueueList[currentItem].init = true initQueueList[currentItem].silent = true
this.addToQueue(initQueueList[currentItem], true) this.addToQueue(initQueueList[currentItem], true)
} }
initQueue.forEach(item => { initQueue.forEach(item => {
initQueueList[item].init = true initQueueList[item].silent = true
this.addToQueue(initQueueList[item]) this.addToQueue(initQueueList[item])
}) })
if (restored){
toast(this.$t('toasts.queueRestored'), 'done', true, 'restoring_queue')
socket.emit('queueRestored')
}
}, },
addToQueue(queueItem, current = false) { addToQueue(queueItem, current = false) {
if (Array.isArray(queueItem)){
if (queueItem.length > 1){
queueItem.forEach((item, i) => {
item.silent = true
this.addToQueue(item)
});
toast(this.$t('toasts.addedMoreToQueue', [queueItem.length]), 'playlist_add_check')
return
}else{
queueItem = queueItem[0]
}
}
this.queueList[queueItem.uuid] = queueItem this.queueList[queueItem.uuid] = queueItem
if (queueItem.downloaded + queueItem.failed == queueItem.size) { if (queueItem.downloaded + queueItem.failed == queueItem.size) {
@ -188,13 +204,13 @@ export default {
} }
} }
if (!queueItem.init) { if (!queueItem.silent) {
toast(this.$t('toasts.addedToQueue', [queueItem.title]), 'playlist_add_check') toast(this.$t('toasts.addedToQueue', [queueItem.title]), 'playlist_add_check')
} }
}, },
updateQueue(update) { updateQueue(update) {
// downloaded and failed default to false? // downloaded and failed default to false?
const { uuid, downloaded, failed, progress, error, data, errid } = update const { uuid, downloaded, failed, progress, conversion, error, data, errid } = update
if (uuid && this.queue.indexOf(uuid) > -1) { if (uuid && this.queue.indexOf(uuid) > -1) {
if (downloaded) { if (downloaded) {
@ -224,6 +240,10 @@ export default {
this.queueList[uuid].progress = progress this.queueList[uuid].progress = progress
$('#bar_' + uuid).css('width', progress + '%') $('#bar_' + uuid).css('width', progress + '%')
} }
if (conversion) {
$('#bar_' + uuid).css('width', (100-conversion) + '%')
}
} }
}, },
removeFromQueue(uuid) { removeFromQueue(uuid) {
@ -339,9 +359,17 @@ export default {
}, },
startDownload(uuid) { startDownload(uuid) {
$('#bar_' + uuid) $('#bar_' + uuid)
.removeClass('converting')
.removeClass('indeterminate') .removeClass('indeterminate')
.addClass('determinate') .addClass('determinate')
}, },
startConversion(uuid) {
$('#bar_' + uuid)
.addClass('converting')
.removeClass('indeterminate')
.addClass('determinate')
.css('width', '100%')
},
showErrorsTab(clickEvent) { showErrorsTab(clickEvent) {
this.$root.$emit('showTabErrors', clickEvent.data.item, clickEvent.target) this.$root.$emit('showTabErrors', clickEvent.data.item, clickEvent.target)
} }

View File

@ -38,7 +38,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -62,7 +61,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -88,7 +86,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -112,7 +109,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -178,7 +174,6 @@
</td> </td>
<td <td
class="table__cell--download clickable" class="table__cell--download clickable"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="track.link" :data-link="track.link"
role="button" role="button"
@ -260,9 +255,6 @@ export default {
e.stopPropagation() e.stopPropagation()
Downloads.sendAddToQueue(e.currentTarget.dataset.link) Downloads.sendAddToQueue(e.currentTarget.dataset.link)
}, },
openQualityModal(e) {
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
},
updated_userSpotifyPlaylists(data) { updated_userSpotifyPlaylists(data) {
this.spotifyPlaylists = data this.spotifyPlaylists = data
}, },

View File

@ -20,7 +20,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -50,7 +49,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -89,9 +87,6 @@ export default {
addToQueue(e) { addToQueue(e) {
Downloads.sendAddToQueue(e.currentTarget.dataset.link) Downloads.sendAddToQueue(e.currentTarget.dataset.link)
}, },
openQualityModal(e) {
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
},
initHome(data) { initHome(data) {
const { const {
playlists: { data: playlistData }, playlists: { data: playlistData },

View File

@ -118,6 +118,7 @@ import { socket } from '@/utils/socket'
import { showView } from '@js/tabs.js' import { showView } from '@js/tabs.js'
import Utils from '@/utils/utils' import Utils from '@/utils/utils'
import EventBus from '@/utils/EventBus' import EventBus from '@/utils/EventBus'
import Downloads from '@/utils/downloads'
export default { export default {
name: 'the-link-analyzer-tab', name: 'the-link-analyzer-tab',
@ -184,6 +185,9 @@ export default {
}, },
notSupported() { notSupported() {
this.link = 'error' this.link = 'error'
},
addToQueue(e) {
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
} }
}, },
mounted() { mounted() {

View File

@ -50,7 +50,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="results.allTab.TOP_RESULT[0].link" :data-link="results.allTab.TOP_RESULT[0].link"
class="download_overlay" class="download_overlay"
@ -115,7 +114,6 @@
</td> </td>
<td <td
class="table__cell--download table__cell--center clickable" class="table__cell--download table__cell--center clickable"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="'https://www.deezer.com/track/' + track.SNG_ID" :data-link="'https://www.deezer.com/track/' + track.SNG_ID"
role="button" role="button"
@ -149,7 +147,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="'https://deezer.com/artist/' + release.ART_ID" :data-link="'https://deezer.com/artist/' + release.ART_ID"
class="download_overlay" class="download_overlay"
@ -181,7 +178,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="'https://deezer.com/album/' + release.ALB_ID" :data-link="'https://deezer.com/album/' + release.ALB_ID"
class="download_overlay" class="download_overlay"
@ -224,7 +220,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="'https://deezer.com/playlist/' + release.PLAYLIST_ID" :data-link="'https://deezer.com/playlist/' + release.PLAYLIST_ID"
class="download_overlay" class="download_overlay"
@ -321,7 +316,6 @@
</td> </td>
<td <td
class="table__cell--download table__cell--center clickable" class="table__cell--download table__cell--center clickable"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="track.link" :data-link="track.link"
role="button" role="button"
@ -353,7 +347,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -391,7 +384,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -422,7 +414,6 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" @click.stop="addToQueue"
:data-link="release.link" :data-link="release.link"
class="download_overlay" class="download_overlay"
@ -625,9 +616,6 @@ export default {
addToQueue(e) { addToQueue(e) {
Downloads.sendAddToQueue(e.currentTarget.dataset.link) Downloads.sendAddToQueue(e.currentTarget.dataset.link)
}, },
openQualityModal(e) {
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
},
numberWithDots: Utils.numberWithDots, numberWithDots: Utils.numberWithDots,
convertDuration: Utils.convertDuration, convertDuration: Utils.convertDuration,
search(type) { search(type) {

View File

@ -53,7 +53,6 @@ export default {
}), }),
mounted() { mounted() {
this.$root.$on('QualityModal:open', this.openModal) this.$root.$on('QualityModal:open', this.openModal)
this.$refs.modal.addEventListener('webkitAnimationEnd', this.handleAnimationEnd) this.$refs.modal.addEventListener('webkitAnimationEnd', this.handleAnimationEnd)
}, },
methods: { methods: {

View File

@ -19,13 +19,16 @@
</h3> </h3>
<div class="inline-flex"> <div class="inline-flex">
<input autocomplete="off" type="password" id="login_input_arl" ref="loginInput" placeholder="ARL" /> <input autocomplete="off" type="password" id="login_input_arl" ref="loginInput" placeholder="ARL" />
<button id="settings_btn_copyArl" @click="copyARLtoClipboard"> <button id="settings_btn_copyArl" class="only_icon" @click="copyARLtoClipboard">
<i class="material-icons">assignment</i> <i class="material-icons">assignment</i>
</button> </button>
</div> </div>
<a href="https://codeberg.org/RemixDev/deemix/wiki/Getting-your-own-ARL" target="_blank"> <a href="https://codeberg.org/RemixDev/deemix/wiki/Getting-your-own-ARL" target="_blank">
{{ $t('settings.login.arl.question') }} {{ $t('settings.login.arl.question') }}
</a> </a>
<a id="settings_btn_applogin" class="hide" href="#" @click="applogin">
Automated login
</a>
<button id="settings_btn_updateArl" @click="login" style="width: 100%;"> <button id="settings_btn_updateArl" @click="login" style="width: 100%;">
{{ $t('settings.login.arl.update') }} {{ $t('settings.login.arl.update') }}
</button> </button>
@ -62,7 +65,12 @@
<h3 class="settings-group__header settings-group__header--with-icon"> <h3 class="settings-group__header settings-group__header--with-icon">
<i class="material-icons">folder</i>{{ $t('settings.downloadPath.title') }} <i class="material-icons">folder</i>{{ $t('settings.downloadPath.title') }}
</h3> </h3>
<input type="text" v-model="settings.downloadLocation" /> <div class="inline-flex">
<input autocomplete="off" type="text" v-model="settings.downloadLocation" />
<button id="select_downloads_folder" class="only_icon hide" @click="selectDownloadFolder">
<i class="material-icons">folder</i>
</button>
</div>
</div> </div>
<div class="settings-group"> <div class="settings-group">
@ -186,6 +194,8 @@
<select v-model="settings.overwriteFile"> <select v-model="settings.overwriteFile">
<option value="y">{{ $t('settings.downloads.overwriteFile.y') }}</option> <option value="y">{{ $t('settings.downloads.overwriteFile.y') }}</option>
<option value="n">{{ $t('settings.downloads.overwriteFile.n') }}</option> <option value="n">{{ $t('settings.downloads.overwriteFile.n') }}</option>
<option value="e">{{ $t('settings.downloads.overwriteFile.e') }}</option>
<option value="b">{{ $t('settings.downloads.overwriteFile.b') }}</option>
<option value="t">{{ $t('settings.downloads.overwriteFile.t') }}</option> <option value="t">{{ $t('settings.downloads.overwriteFile.t') }}</option>
</select> </select>
</div> </div>
@ -264,12 +274,14 @@
<div class="input_group"> <div class="input_group">
<p class="input_group_text">{{ $t('settings.covers.localArtworkSize') }}</p> <p class="input_group_text">{{ $t('settings.covers.localArtworkSize') }}</p>
<input type="number" min="100" max="1800" step="100" v-model.number="settings.localArtworkSize" /> <input type="number" min="100" max="10000" step="100" v-model.number="settings.localArtworkSize" />
<p v-if="settings.localArtworkSize > 1200" class="input_group_text" style="opacity: 0.75; color: #ffcc22;"> {{ $t('settings.covers.imageSizeWarning') }}</p>
</div> </div>
<div class="input_group"> <div class="input_group">
<p class="input_group_text">{{ $t('settings.covers.embeddedArtworkSize') }}</p> <p class="input_group_text">{{ $t('settings.covers.embeddedArtworkSize') }}</p>
<input type="number" min="100" max="1800" step="100" v-model.number="settings.embeddedArtworkSize" /> <input type="number" min="100" max="10000" step="100" v-model.number="settings.embeddedArtworkSize" />
<p v-if="settings.embeddedArtworkSize > 1200" class="input_group_text" style="opacity: 0.75; color: #ffcc22;"> {{ $t('settings.covers.imageSizeWarning') }}</p>
</div> </div>
<div class="input_group"> <div class="input_group">
@ -281,6 +293,12 @@
</select> </select>
</div> </div>
<label class="with_checkbox">
<input type="checkbox" v-model="settings.embeddedArtworkPNG" />
<span class="checkbox_text">{{ $t('settings.covers.embeddedArtworkPNG') }}</span>
</label>
<p v-if="settings.embeddedArtworkPNG" style="opacity: 0.75; color: #ffcc22;"> {{ $t('settings.covers.embeddedPNGWarning') }}</p>
<div class="input_group"> <div class="input_group">
<p class="input_group_text">{{ $t('settings.covers.jpegImageQuality') }}</p> <p class="input_group_text">{{ $t('settings.covers.jpegImageQuality') }}</p>
<input type="number" min="1" max="100" v-model.number="settings.jpegImageQuality" /> <input type="number" min="1" max="100" v-model.number="settings.jpegImageQuality" />
@ -727,6 +745,8 @@ export default {
socket.on('updateSettings', this.updateSettings) socket.on('updateSettings', this.updateSettings)
socket.on('accountChanged', this.accountChanged) socket.on('accountChanged', this.accountChanged)
socket.on('familyAccounts', this.initAccounts) socket.on('familyAccounts', this.initAccounts)
socket.on('downloadFolderSelected', this.downloadFolderSelected)
socket.on('applogin_arl', this.setArl)
}, },
methods: { methods: {
revertSettings() { revertSettings() {
@ -768,6 +788,13 @@ export default {
socket.emit('saveSettings', this.lastSettings, this.lastCredentials, changed ? this.lastUser : false) socket.emit('saveSettings', this.lastSettings, this.lastCredentials, changed ? this.lastUser : false)
}, },
selectDownloadFolder() {
if (window.clientMode) socket.emit('selectDownloadFolder')
},
downloadFolderSelected(folder){
console.log(folder)
this.settings.downloadLocation = folder
},
loadSettings(settings, spotifyCredentials, defaults = null) { loadSettings(settings, spotifyCredentials, defaults = null) {
if (defaults) { if (defaults) {
this.defaultSettings = { ...defaults } this.defaultSettings = { ...defaults }
@ -784,6 +811,14 @@ export default {
socket.emit('login', arl, true, this.accountNum) socket.emit('login', arl, true, this.accountNum)
} }
}, },
applogin(e) {
e.preventDefault()
if (window.clientMode) socket.emit('applogin')
},
setArl(arl) {
this.$refs.loginInput.value = arl
this.login()
},
changeAccount() { changeAccount() {
socket.emit('changeAccount', this.accountNum) socket.emit('changeAccount', this.accountNum)
}, },

View File

@ -9,11 +9,11 @@
<span class="main_tablinks_text">{{ $t('sidebar.search') }}</span> <span class="main_tablinks_text">{{ $t('sidebar.search') }}</span>
</span> </span>
<span id="main_charts_tablink" class="main_tablinks" role="link" aria-label="charts"> <span id="main_charts_tablink" class="main_tablinks" role="link" aria-label="charts">
<i class="material-icons side_icon">bubble_chart</i> <i class="material-icons side_icon">show_chart</i>
<span class="main_tablinks_text">{{ $t('sidebar.charts') }}</span> <span class="main_tablinks_text">{{ $t('sidebar.charts') }}</span>
</span> </span>
<span id="main_favorites_tablink" class="main_tablinks" role="link" aria-label="favorites"> <span id="main_favorites_tablink" class="main_tablinks" role="link" aria-label="favorites">
<i class="material-icons side_icon">album</i> <i class="material-icons side_icon">star</i>
<span class="main_tablinks_text">{{ $t('sidebar.favorites') }}</span> <span class="main_tablinks_text">{{ $t('sidebar.favorites') }}</span>
</span> </span>
<span id="main_analyzer_tablink" class="main_tablinks" role="link" aria-label="link analyzer"> <span id="main_analyzer_tablink" class="main_tablinks" role="link" aria-label="link analyzer">
@ -194,4 +194,3 @@ export default {
} }
} }
</script> </script>

View File

@ -30,7 +30,10 @@ export default {
onTimeUpdate() { onTimeUpdate() {
// Prevents first time entering in this function // Prevents first time entering in this function
if (isNaN(this.$refs.preview.duration)) return if (isNaN(this.$refs.preview.duration)) return
if (this.$refs.preview.currentTime <= this.$refs.preview.duration - 1) return let duration = this.$refs.preview.duration
if (!isFinite(duration)) duration = 30
if (duration - this.$refs.preview.currentTime >= 1) return
if (this.previewStopped) return
$(this.$refs.preview).animate({ volume: 0 }, 800) $(this.$refs.preview).animate({ volume: 0 }, 800)

View File

@ -133,15 +133,10 @@
</table> </table>
<span v-if="label" style="opacity: 0.4; margin-top: 8px; display: inline-block; font-size: 13px;">{{ label }}</span> <span v-if="label" style="opacity: 0.4; margin-top: 8px; display: inline-block; font-size: 13px;">{{ label }}</span>
<footer> <footer>
<button @contextmenu.prevent="openQualityModal" @click.stop="addToQueue" :data-link="link"> <button @click.stop="addToQueue" :data-link="link">
{{ `${$t('globals.download', [$tc(`globals.listTabs.${type}`, 1)])}` }} {{ `${$t('globals.download', [$tc(`globals.listTabs.${type}`, 1)])}` }}
</button> </button>
<button <button class="with_icon" @click.stop="addToQueue" :data-link="selectedLinks()">
class="with_icon"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue"
:data-link="selectedLinks()"
>
{{ $t('tracklist.downloadSelection') }}<i class="material-icons">file_download</i> {{ $t('tracklist.downloadSelection') }}<i class="material-icons">file_download</i>
</button> </button>
<button class="back-button" @click="backTab">{{ $t('globals.back') }}</button> <button class="back-button" @click="backTab">{{ $t('globals.back') }}</button>
@ -191,9 +186,6 @@ export default {
addToQueue(e) { addToQueue(e) {
Downloads.sendAddToQueue(e.currentTarget.dataset.link) Downloads.sendAddToQueue(e.currentTarget.dataset.link)
}, },
openQualityModal(e) {
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
},
toggleAll(e) { toggleAll(e) {
this.body.forEach(item => { this.body.forEach(item => {
if (item.type == 'track') { if (item.type == 'track') {

32
src/js/qualities.js Normal file
View File

@ -0,0 +1,32 @@
export default [
{
objName: 'flac',
label: 'FLAC',
value: 9
},
{
objName: '320kbps',
label: 'MP3 320kbps',
value: 3
},
{
objName: '128kbps',
label: 'MP3 128kbps',
value: 1
},
{
objName: 'realityAudioHQ',
label: '360 Reality Audio [HQ]',
value: 15
},
{
objName: 'realityAudioMQ',
label: '360 Reality Audio [MQ]',
value: 14
},
{
objName: 'realityAudioLQ',
label: '360 Reality Audio [LQ]',
value: 13
}
]

12
src/jsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"checkJs": true,
"baseUrl": ".",
"paths": {
"@/*": ["./*"],
"@js/*": ["./js/*"],
"@components/*": ["./components/*"]
}
},
"exclude": ["assets/**/*", "styles/**/*"]
}

346
src/lang/ar.js Normal file
View File

@ -0,0 +1,346 @@
const ar = {
globals: {
welcome: 'مرحبأ بك في ديمكس',
back: 'رجوع',
loading: 'جار التحميل',
download: 'تحميل {0}',
by: 'بواسطة {0}',
in: 'في {0}',
download_hint: 'تحميل',
play_hint: 'تشغيل',
toggle_download_tab_hint: 'عرض/اخفاء',
clean_queue_hint: 'تم المسح',
cancel_queue_hint: 'الغاء الكل',
listTabs: {
empty: '',
all: 'الكل',
top_result: 'افضل النتائج',
album: 'البوم | البومات',
artist: 'فنان | فنانون',
single: 'اغنية | اغنية',
title: 'عنوان | عناوين',
track: 'مقطع | مقاطع',
trackN: '0 مقاطع | {n} مقطع | {n} مقطع',
releaseN: '0 اصدار | {n} اصدار | {n} اصدار',
playlist: 'قائمة تشغيل | قوائم تشغيل',
compile: 'مجموعة | مجموعات',
ep: 'ep | eps',
spotifyPlaylist: 'قائمة تشغيل سبوتفاي | قوائم تشغيل سبوتفاي',
releaseDate: 'تاريخ الاصدار',
error: 'خطأ'
}
},
about: {
titles: {
usefulLinks: 'روابط مهمة',
bugReports: 'ابلاغ عن مشكلة',
contributing: 'مساهمة',
donations: 'التبرع',
license: 'الرخصة'
},
subtitles: {
bugReports: "هل هناك شيء لا يعمل في ديمكس؟ أخبرنا",
contributing: 'تريد المساهمة في هذا المشروع؟ يمكنك القيام بذلك بعدة طرق',
donations: 'تريد المساهمة مادياً؟ يمكنك التبرع'
},
usesLibrary: 'هذا البرنامج يستخدم مكتبة <strong>ديمكس</strong> والتي يمكنك استخدامها لإنشاء واجهة مستخدم خاصة بك لديمكس.',
thanks: `شكرا لـ <strong>rtonno</strong>, و <strong>uhwot</strong> و <strong>lollilol</strong> لمساعدتي في هذا المشروع و لـ <strong>BasCurtiz</strong> و <strong>scarvimane</strong> لصنع الايقونة.`,
upToDate: `تابع اخر التحديثات في قناة الاخبار على تلكرام <a href="https://t.me/RemixDevNews" target="_blank"></a>.`,
officialWebsite: 'الموقع الرسمي',
officialRepo: 'مستودع المكتبة الرسمي',
officialWebuiRepo: 'مستودع واجهة الويب الرسمي',
officialSubreddit: 'السب ريدت الرسمي',
newsChannel: 'قناة الاخبار',
questions: `إذا كانت لديك أسئلة أو مشاكل في التطبيق ، فابحث عن حل في السب ريدت اولاً <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a> بعد ذلك ، إذا لم تعثر على أي شيء ، يمكنك نشرمشكلتك على السب ريدت .`,
beforeReporting: `قبل ان تبلغ عن خطأ، تأكد من أنك تشغل أحدث إصدار من التطبيق وأن ما تريد الإبلاغ عنه هو في الواقع خطأ وليس مشكلة من جهتك.`,
beSure: `تأكد من أن الخطأ يمكن إعادة إنتاجه على أجهزة أخرى و ايضاً <strong>لا</strong> تبلغ علة خطأ تم التبليغ عنه سابقاً.`,
duplicateReports: 'سيتم إغلاق تقارير الأخطاء المكررة ، لذلك ترقب ذلك.',
dontOpenIssues: `<strong>DO NOT</strong> open issues for asking questions, there is a subreddit for that.`,
newUI: `If you're fluent in python you could try to make a new UI for the app using the base library, or fix bugs in the library with a pull request on the <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repo</a>.`,
acceptFeatures: `أقبل اقتراحات الميزات أيضًا ، ولكن لا أشياء معقدة ، فقط اشياء يمكنني تنفيذها مباشرة في التطبيق وليس في المكتبة.`,
otherLanguages: `إذا كنت تجيد لغة برمجة أخرى ، يمكنك محاولة تحويل ديمكس إلى لغات برمجة أخرى!`,
understandingCode: `أنت بحاجة إلى مساعدة في فهم الكود؟ فقط اتصل بـ RemixDev على تيليكرام او ريديت.`,
contributeWebUI: `If you know Vue.js (JavaScript), HTML or CSS you could contribute to the <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`,
itsFree: `يجب ان تتذكر ان <strong>هذا هو مشروع مجاني</strong> <strong>و عليك دعم الفنانين المفضلين لك قبل ان تدعم مطورين البرنامج</strong>.`,
notObligated: `لا تشعر بالالتزام بالتبرع ، لكني أقدر ذلك على أي حال!`,
lincensedUnder: `This work is licensed under the
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"
>GNU General Public License 3.0</a
>.`
},
charts: {
title: 'قائمة الجداول',
changeCountry: 'تغيير الدولة',
download: 'تحميل قائمة الجدول'
},
errors: {
title: 'خطأ في {0}',
ids: {
invalidURL: 'الرابط غير صحيح',
unsupportedURL: 'الرابط غير متاح حتى الانً',
ISRCnotOnDeezer: 'رمز المقطع غير متوفر في ديزر',
notYourPrivatePlaylist: "لا يمكنك تحميل قوائم التشغيل الخاصة و المخفية.",
spotifyDisabled: 'لم يتم اعداد ميزات سبوتفاي بالطرقة الصحيحة .',
trackNotOnDeezer: 'المقطع لا يوجد في ديزر!',
albumNotOnDeezer: 'الالبوم لا يوجد في ديزر!',
notOnDeezer: 'المقطع لا يوجد في ديزر!',
notEncoded: 'لم يتم تشفير المقطع حتى الانً!',
notEncodedNoAlternative: 'لم يتم تشفير المقطع حتى الآن ولم يتم العثور على بديل!',
wrongBitrate: 'لم يتم العثور على المقطع في الدقة المطلوبة.',
wrongBitrateNoAlternative: 'لم يتم العثور على المقطع في الدقة المطلوبة و لا توجد دقة بديلة!',
no360RA: 'المقطع غير متوفر في Reality Audio 360.',
notAvailable: "المقطع غير متوفر في سيرفرات ديزر!",
notAvailableNoAlternative: "المقطع غير متوفر في سيرفرات ديزر و لا يوجد بديل حتى الان!"
}
},
favorites: {
title: 'المفضلات',
noPlaylists: 'لا يوجد قوائم تشغيل',
noAlbums: 'لم لا توجد البومات مفضلة',
noArtists: 'لا يوجد فنانين مفضلين',
noTracks: 'لا توجد مقاطع مفضلة'
},
home: {
needTologin: 'يجب عليك التسجيل في حساب ديزر قبل بدء التحميل.',
openSettings: 'فتح الاعدادات',
sections: {
popularPlaylists: 'قوائم تشغيل مشهورة',
popularAlbums: 'اكثر الالبومات سماعأ'
}
},
linkAnalyzer: {
info: 'يمكنك استخدام هذا القسم للعثور على مزيد من المعلومات حول الرابط الذي تحاول تنزيله.',
useful:
" كمثال هذا مفيد إذا كنت تحاول تنزيل بعض المقاطع الغير المتاحة في بلدك وتريد معرفة مكان توفرها .",
linkNotSupported: 'هذا الرابط غير معتمد حتى الآن',
linkNotSupportedYet: 'يبدو أن هذا الرابط غير معتمد حتى الآن ، حاول تحليل رابط آخر.',
table: {
id: 'ID',
isrc: 'ISRC',
upc: 'UPC',
duration: 'المدة الزمنية',
diskNumber: 'رقم القرص',
trackNumber: 'رقم المقطع',
releaseDate: 'تاريخ الاصدار',
bpm: 'BPM',
label: 'Label',
recordType: 'نوع التسجيل',
genres: 'النوع الفني',
tracklist: 'قائمة المقاطع'
}
},
search: {
startSearching: 'ابدأ البحث!',
description:
'يمكنك البحث عن مقطع ، ألبوم كامل ، فنان ، قائمة تشغيل .... كل شيء! يمكنك أيضًا لصق رابط ديزر',
fans: '{0} متابعون',
noResults: 'لا يوجد نتائج',
noResultsTrack: 'لم يتم العثور على مقاطع',
noResultsAlbum: 'لم يتم العثور على البومات',
noResultsArtist: 'لم يتم العثور على فنانين',
noResultsPlaylist: 'لم يتم العثور على قوائم تشغيل'
},
searchbar: 'ابحث عن أي شيء تريده (أو الصق رابط)',
downloads: 'التحميلات',
toasts: {
addedToQueue: '{0} تمت إلأضافة إلى قائمة الانتظار',
alreadyInQueue: '{0} حالياً في قائمة الانتظار!',
finishDownload: '{0} انتهى تحميل.',
allDownloaded: 'اكتملت جميع التنزيلات!',
refreshFavs: 'اكتمل التحديث!',
loggingIn: 'جار تسجيل الدخول...',
loggedIn: 'تم تسجيل الدخول',
alreadyLogged: 'تم تسجيل الدخول بالفعل',
loginFailed: "تعذر تسجيل الدخول",
loggedOut: 'تم تسجيل الخروج',
cancellingCurrentItem: 'جار الغاء العنصر الحالي.',
currentItemCancelled: 'تم الغاء العنصر الحالي.',
startAddingArtist: 'جار اضافة {0} البوم الى قائمة الانتضار',
finishAddingArtist: 'تم اضافة {0} البوم الى قائمة الانتضار',
startConvertingSpotifyPlaylist: 'جار تحويل مقاطع سبوتفاي الى مقاطع ديزر',
finishConvertingSpotifyPlaylist: 'تم تحويل قائمة تشغيل سبوتفاي',
loginNeededToDownload: 'يجب عليك تسجيل الدخول لتحميل المقاطع!'
},
settings: {
title: 'الاعدادات',
languages: 'اللغات',
login: {
title: 'تسجيل الدخول',
loggedIn: 'تم تسجيل الدخول كـ {username}',
arl: {
question: 'كيفية الحصول علة ARL',
update: 'ارفع ال ARL'
},
logout: 'تسجيل الخروج'
},
appearance: {
title: 'المظهر',
slimDownloadTab: 'لوحة التحميل الرفيعة'
},
downloadPath: {
title: 'مسار التحميل'
},
templates: {
title: 'القوالب',
tracknameTemplate: 'قالب اسم المقطع',
albumTracknameTemplate: 'قالب مقطع الالبوم',
playlistTracknameTemplate: 'قالب مقطع قائمة التشغيل'
},
folders: {
title: 'الملفات',
createPlaylistFolder: 'اصنع ملف لقائمة التشغيل',
playlistNameTemplate: 'قالب ملف قائمة التشغيل',
createArtistFolder: 'اصنع ملف للفنان',
artistNameTemplate: 'قالب ملف الفنان',
createAlbumFolder: 'اصنع ملف للالبوم',
albumNameTemplate: 'قالب ملف الالبوم',
createCDFolder: 'اصنع ملف للاقراص',
createStructurePlaylist: 'اصنع هيكل مجلدات لقوائم التشغيل',
createSingleFolder: 'اصنع هيكل مجلدات لالبومات ذات الاغنية الواحدة'
},
trackTitles: {
title: 'عنوان المقطع',
padTracks: 'Pad tracks',
paddingSize: 'Overwrite padding size',
illegalCharacterReplacer: 'محول الكتابات الغير مسموح بها'
},
downloads: {
title: 'التحميلات',
queueConcurrency: 'التنزيلات المتزامنة',
maxBitrate: {
title: 'الدقة المفضلة',
9: 'FLAC 1411kbps',
3: 'MP3 320kbps',
1: 'MP3 128kbps'
},
overwriteFile: {
title: 'هل يمكنني استبدال الملفات?',
y: 'نعم, استبدال الملفات',
n: "لا, لا تبدل الملفات",
t: 'استبدل العلامات فقط',
b: 'لا ، احتفظ بالملفين وأضف رقمًا إلى الملف المكرر'
},
fallbackBitrate: 'تراجع الدقة',
fallbackSearch: 'تراجع البحث',
logErrors: 'إنشاء ملفات سجل للأخطاء',
logSearched: 'إنشاء ملفات سجل للمقاطع التي تم البحث عنها',
createM3U8File: 'انشاء ملف لقوائم التشغيل',
syncedLyrics: 'انشاء ملف لكلمات الاغنية',
playlistFilenameTemplate: 'قالب اسم ملف قائمة التشغيل',
saveDownloadQueue: 'حفظ قائمة انتظار التنزيل عند إغلاق التطبيق'
},
covers: {
title: 'غلاف الالبوم',
saveArtwork: 'احفظ الغلاف',
coverImageTemplate: 'تغطية قالب الاسم',
saveArtworkArtist: 'احفظ صورة الفنان',
artistImageTemplate: 'قالب صورة الفنان',
localArtworkSize: 'حجم الصورة',
embeddedArtworkSize: 'حجم الصورة المدمجة',
localArtworkFormat: {
title: 'بأي صيغة تريد حفظ الصورة?',
jpg: 'jpeg صورة',
png: 'png صورة',
both: 'الاثنين png و jpeg'
},
jpegImageQuality: 'JPEG دقة صورة'
},
tags: {
head: 'العلامات التي يتم حفظها',
title: 'العنوان',
artist: 'الفنان',
album: 'الالبوم',
cover: 'الغلاف',
trackNumber: 'رقم المقطع',
trackTotal: 'مجموع المقاطع',
discNumber: 'رقم القرص',
discTotal: 'مجموع الاقراص',
albumArtist: 'فنان الالبوم',
genre: 'Genre',
year: 'السنة',
date: 'التاريخ',
explicit: 'كلمات اغنية صريحة للكبار',
isrc: 'ISRC',
length: 'طول المقطع',
barcode: 'Album Barcode (UPC)',
bpm: 'BPM',
replayGain: 'Replay Gain',
label: 'Album Label',
lyrics: 'كلمات غير متزامنة',
copyright: 'حقوق النشر',
composer: 'ملحن',
involvedPeople: 'الناس المشتركون'
},
other: {
title: 'غير',
savePlaylistAsCompilation: 'حفظ قوائم التشغيل كمجموعة',
useNullSeparator: 'استخدم فاصل فارغ',
saveID3v1: 'احفظ ملف ID3v1',
multiArtistSeparator: {
title: 'كيف تريد فصل الفنانين?',
nothing: 'احفظ الفنان الرئيسي فقط',
default: 'استخدام المواصفات القياسية',
andFeat: 'استخدام& و feat.',
using: 'استخدام "{0}"'
},
singleAlbumArtist: 'احفظ فقط فنان الألبوم الرئيسي',
albumVariousArtists: 'احتفظ بـ "فنانين متنوعين" في ألبوم الفنانين',
removeAlbumVersion: 'إزالة "إصدار الألبوم" من عنوان المسار',
removeDuplicateArtists: 'إزالة مجموعات الفنانين',
dateFormat: {
title: 'صيغة التاريخ لملفات flac',
year: 'س س س س',
month: 'ش ش',
day: 'ي ي'
},
featuredToTitle: {
title: 'ماذا علي أن أفعل مع الفنانين الغير رئيسيين ?',
0: 'لا شيء',
1: 'حذفه من العنوان',
3: 'حذفه من عنوان الاغنية و الالبوم',
2: 'وضعه في العنوان'
},
titleCasing: 'نوع كتابة العناون',
artistCasing: 'نوع كتابة الفنان',
casing: {
nothing: 'بدون تغيير',
lower: 'احرف صغيرة',
upper: 'احرف كبيرة',
start: 'حرف كبير في بداية كل كلمة',
sentence: 'مثل جملة'
},
previewVolume: 'معاينة الحجم',
executeCommand: {
title: 'الأمر للتنفيذ بعد التنزيل',
description: 'اتركه فارغًا بدون إجراء'
}
},
spotify: {
title: 'مميزات سبوتفاي',
clientID: 'معرف عميل سبوتفاي',
clientSecret: 'الكود السري لعميل سبوتفاي',
username: 'اسم مستخدم سبوتفاي'
},
reset: 'إعادة تعيين إلى الافتراضي',
save: 'حفظ',
toasts: {
init: 'تم تحميل الإعدادات!',
update: 'تم تحديث الاعدادات!',
ARLcopied: 'تم نسخ ARL إلى الحافظة'
}
},
sidebar: {
home: 'الرئيسية',
search: 'بحث',
charts: 'قائمة الجداول',
favorites: 'المفضلة',
linkAnalyzer: 'محلل الروابط',
settings: 'الاعدادات',
about: 'حول'
},
tracklist: {
downloadSelection: 'تحميل الاختيار'
}
}
export default ar

View File

@ -4,204 +4,199 @@ const de = {
back: 'zurück', back: 'zurück',
loading: 'lädt', loading: 'lädt',
download: 'Download {0}', download: 'Download {0}',
by: 'um {0}', by: 'von {0}',
in: 'in {0}', in: 'in {0}',
download_hint: 'Download', download_hint: 'Download',
play_hint: 'Abspielen', play_hint: 'Play',
toggle_download_tab_hint: 'Einblenden/Ausblenden', toggle_download_tab_hint: 'Erweitern/Minimieren',
clean_queue_hint: 'Fertige löschen', clean_queue_hint: 'Entferne vollständige',
cancel_queue_hint: 'Alle abbrechen', cancel_queue_hint: 'Alle abbrechen',
listTabs: { listTabs: {
empty: '', empty: '',
all: 'alle', all: 'alle',
top_result: 'top-ergebnis', top_result: 'Top Ergebnis',
album: 'album | alben', album: 'Album | Alben',
artist: 'künstler | künstler', artist: 'Künstler | Künstler',
single: 'single | singles', single: 'Single | Singles',
title: 'titel | titel', title: 'Titel | Titel',
track: 'track | tracks', track: 'Track | Tracks',
trackN: '0 tracks | {n} track | {n} tracks', trackN: '0 Tracks | {n} Track | {n} Tracks',
releaseN: '0 veröffentlichungen | {n} veröffentlichung | {n} veröffentlichungen', releaseN: '0 Releases | {n} Release | {n} Releases',
playlist: 'playlist | playlisten', playlist: 'Playlist | Playlists',
compile: 'compilation | compilations', compile: 'Sammlung | Sammlungen',
ep: 'ep | eps', ep: 'EP | EPs',
spotifyPlaylist: 'spotify playlist | spotify playlists', spotifyPlaylist: 'Spotify Playlist | Spotify Playlists',
releaseDate: 'veröffentlichungsdatum', releaseDate: 'Veröffentlichungsdatum',
error: 'fehler' error: 'Fehler'
} }
}, },
about: { about: {
titles: { titles: {
usefulLinks: 'Hilfreiche Links', usefulLinks: 'Nützliche Links',
bugReports: 'Fehlerberichte', bugReports: 'Fehlermeldung',
contributing: 'Mitwirkende', contributing: 'Mitwirkende',
donations: 'Spenden', donations: 'Spenden',
license: 'Lizenz' license: 'Lizenz'
}, },
subtitles: { subtitles: {
bugReports: "Gibt es etwas, das im Deemix nicht funktioniert? Teil es uns mit!", bugReports: 'Funktioniert etwas in Deemix nicht? Sag uns bescheid!',
contributing: 'du möchtest zu diesem Projekt beitragen? Das kannst du auf verschiedene Weise tun!', contributing: 'Du möchtest bei dem Projekt helfen? Das kannst du auf verschiedene Arten machen!',
donations: 'du möchtest einen monetären Beitrag leisten? Gib uns eine Spende!' donations: 'Du möchtest deemix finanziell unterstützen? Dann lasse eine kleine Spende da!'
}, },
usesLibrary: 'Diese App verwendet die <strong>deemix</strong> Bibliothek, die du verwenden kannst, um Deine eigene UI für Deemix zu erstellen.', usesLibrary: 'Dieses Programm nutzt die <strong>deemix</strong> Bibliothek, die du dazu nutzen kannst deine eigene deemix UI zu erstellen.',
thanks: `Danke an <strong>rtonno</strong>, <strong>uhwot</strong> und <strong>lollilol</strong> für die Hilfe bei diesem Projekt und an <strong>BasCurtiz</strong> und <strong>scarvimane</strong> für das Design der Icons.`, thanks: 'Ein Dankeschön geht an <strong>rtonno</strong>, <strong>uhwot</strong> and <strong>lollilol</strong> für die Hilfe bei diesem Projekt und an <strong>BasCurtiz</strong> and <strong>scarvimane</strong> für die Erstellung des Logos.',
upToDate: `Bleibe mit den Aktualisierungen auf dem Laufenden, indem du dem <a href="https://t.me/RemixDevNews" target="_blank">Nachrichtenkanal</a> auf Telegram folgst.`, upToDate: 'Bleib auf dem Laufenden mit den Updates indem du dem <a href="https://t.me/RemixDevNews" target="_blank">News Channel</a> auf Telegram folgst.',
officialWebsite: 'Offizielle Webseite', officialWebsite: 'Offizielle Website',
officialRepo: 'Offizielle Library Repository', officialRepo: 'Offizielle Library Repository',
officialWebuiRepo: 'Offizielle WebUI Repository', officialWebuiRepo: 'Offizielle WebUI Repository',
officialSubreddit: 'Offizieller Subreddit', officialSubreddit: 'Offizieller Subreddit',
newsChannel: 'News Kanal', newsChannel: 'News Channel',
questions: `Wenn du Fragen oder Probleme mit der App hast, suche zuerst nach einer Lösung im <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a>. Wenn du dann nichts findest, kannst du einen Beitrag mit Deinem Thema auf dem subreddit verfassen.`, questions: 'Bei Fragen oder Problemen mit der App, suche als erstes nach einer Lösung im <a href="https://www.reddit.com/r/deemix" target="_blank">Subreddit</a>. Wenn du da nichts findest, kannst du einen Beitrag mit deinen Problem auf dem Subreddit verfassen.',
beforeReporting: `Bevor du einen Fehler meldest, stelle sicher, dass du die neueste Version der App benutzt und dass das, was du melden möchtest, tatsächlich ein Fehler ist und nicht etwas, das nur auf deiner Seite falsch ist.`, beforeReporting: 'Bevor du einen Bug meldest, stelle sicher, dass du die neueste Version der App hast und dass das, was du melden möchtest, tatsächlich ein Bug ist und nicht nur bei dir falsch ist.',
beSure: `Vergewissere dich, dass der Fehler auf einem anderen Rechner reproduzierbar ist und auch <stark>DO NOT</stark> melde einen Fehler, wenn er bereits gemeldet wurde.`, beSure: 'Stelle sicher, dass der Bug auf anderen Computern auch vorhanden ist <strong>MELDEN NICHT</strong> einen Bug, wenn er schon gemeldet worden ist.',
duplicateReports: 'Doppelte Fehlerberichte werden geschlossen, also behalte das im Auge.', duplicateReports: 'Doppelte Fehlerberichte werden geschlossen, achte darauf.',
dontOpenIssues: `Erstelle <strong>KEINE</strong> Einträge, um Fragen zu stellen, dafür gibt es einen Unterpunkt.`, dontOpenIssues: '<strong>ERSTELLE KEINE</strong> Fehlermeldungen um Fragen zu stellen, es gibt einen Subreddit dafür.',
newUI: `Wenn du dich mit Python auskennst, könntest du versuchen, ein neues UI für die Anwendung zu erstellen, indem du die Basisbibliothek benutzt, oder Fehler in der Bibliothek mit einer Pull-Anfrage auf der <a href="https://codeberg.org/RemixDev/deemix" target="_blank">Repo</a> behebst.`, newUI: 'Wenn du Python fließend beherrschst, kannst du versuchen, mit hilfe der base library eine neue Benutzeroberfläche für die App zu erstellen oder Fehler in der Bibliothek mit einem Pull-Request in der <a href="https://codeberg.org/RemixDev/deemix" target="_blank">deemix Repo</a> zu beheben.',
acceptFeatures: `Ich akzeptiere auch Features, aber keine komplexen Dinge, da sie direkt in der App und nicht in der Bibliothek implementiert werden können.`, acceptFeatures: 'Ich akzeptiere auch Funktionen, aber keine komplexen Dinge, da sie direkt in der App und nicht in der Bibliothek implementiert werden können.',
otherLanguages: `Wenn du eine andere Programmiersprache fließend beherrschst, könntest du versuchen, deemix in andere Programmiersprachen zu portieren!`, otherLanguages: 'Wenn du eine andere Programmiersprache fließend beherrschst, kannst du versuchen, deemix in andere Programmiersprachen zu portieren!',
understandingCode: `Sie benötigen Hilfe beim Verständnis des Codes? Drücken Sie einfach RemixDev auf Telegram oder Reddit.`, understandingCode: 'Du benötigst Hilfe beim verstehen des Codes? Frag einfach RemixDev auf Telegram oder Reddit.',
contributeWebUI: `Wenn du Vue.js (JavaScript), HTML oder CSS kennst, könntest du zum <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a> beitragen.`, contributeWebUI: 'Wenn du Vue.js (JavaScript) oder HTML und CSS kennst, könntest du etwas zum <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a> beitragen.',
itsFree: `Du solltest daran denken, dass dies ist ein <strong>freies Projekt</strong> ist und <strong>Du solltest die Künstler, die du liebst, unterstützen<strong>, bevor du die Entwickler unterstützt.`, itsFree: 'Du solltest im Kopf behalten das <strong>dies ein kostenloses Projekt ist</strong> und <strong>Du solltest die Künstler unterstützen, die du magst </strong> bevor du die Entwickler unterstützt.',
notObligated: `Fühle dich nicht verpflichtet zu spenden, wir schätzen deinen Beitrag trotzdem!`, notObligated: 'Fühle dich nicht gezwungen zu spenden, danke, dass du deemix verwendest!',
lincensedunder: `Diese Arbeit ist lizensiert unter einer lincensedUnder: 'Diese Arbeit ist lizensiert unter der <a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GNU General Public License 3.0</a>.'
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"
>GNU General Public License 3.0</a
>.`
}, },
charts: { charts: {
title: 'Charts', title: 'Charts',
changeCountry: 'Land ändern', changeCountry: 'Land wechseln',
download: 'Charts herunterladen' download: 'Download Chart'
}, },
errors: { errors: {
title: 'Fehler für {0}', title: 'Errors für {0}',
ids: { ids: {
invaliduRL: 'URL nicht erkannt', invalidURL: 'URL nicht erkannt',
unsupporteduRL: 'URL noch nicht unterstützt', unsupportedURL: 'URL noch nicht unterstützt',
ISRCnotOnDeezer: 'Titel ISRC ist auf deezer nicht verfügbar', ISRCnotOnDeezer: 'Track ISRC ist auf deezer nicht verfügbar',
notYourPrivatePlaylist: "Du kannst keine privaten Playlisten anderer herunterladen.", notYourPrivatePlaylist: "Du kannst keine privaten Playlisten anderer herunterladen.",
spotifyDisabled: 'Spotify Features sind nicht korrekt eingerichtet.', spotifyDisabled: 'Spotify-Funktionen sind nicht richtig eingerichtet',
trackNotOnDeezer: 'Titel auf der Deezer nicht gefunden!', trackNotOnDeezer: 'Track ist nicht verfügbar auf Deezer!',
albumNotOnDeezer: 'Album auf der Deezer nicht gefunden!', albumNotOnDeezer: 'Album auf Deezer nicht gefunden!',
notOnDeezer: 'Titel bei Deezer nicht verfügbar!', notOnDeezer: 'Track auf Deezer nicht verfügbar!',
notEncoded: 'Titel noch nicht kodiert!', notEncoded: 'Track noch nicht codiert!',
notEncodedNoAlternative: 'Titel noch nicht kodiert und keine Alternative gefunden!', notEncodedNoAlternative: 'Track noch nicht codiert und keine Alternative gefunden!',
wrongBitrate: 'Titel mit der gewünschten Bitrate nicht gefunden.', wrongBitrate: 'Track mit gewünschter Bitrate nicht gefunden.',
wrongBitrateNoAlternative: 'Titel mit der gewünschten Bitrate nicht gefunden und keine Alternative gefunden!', wrongBitrateNoAlternative: 'Track mit gewünschter Bitrate nicht gefunden und keine Alternative gefunden!',
no360RA: 'Der Titel ist im Reality Audio 360 Format nicht verfügbar.', no360RA: 'Track ist nicht verfügbar in Reality Audio 360.',
notAvailable: "Titel auf den Servern von deezer nicht verfügbar!", notAvailable: "Track ist noch nicht verfügbar auf den Servern von Deezer!",
notAvailableNoAlternative: "Titel auf den Servern von deezer nicht verfügbar und keine Alternative gefunden!" notAvailableNoAlternative: "Track ist noch nicht verfügbar auf den Servern von Deezer und keine Alternativen gefunden!!"
} }
}, },
favorites: { favorites: {
title: 'Favoriten', title: 'Favoriten',
noPlaylists: 'Keine Playlisten gefunden', noPlaylists: 'Keine Playlist gefunden',
noAlbums: 'Keine Album-Favoriten gefunden', noAlbums: 'Keine favorisierten Alben gefunden',
noArtists: 'Keine Künstler-Favoriten gefunden', noArtists: 'Keine favorisierten Künstler gefunden',
noTracks: 'Keine Titel-Favoriten gefunden' noTracks: 'Keine favorisierten Tracks gefunden'
}, },
home: { home: {
needTologin: 'Du musst dich in dein Deezer-Konto einloggen, bevor du mit dem Download beginnen kannst.', needTologin: 'Du musst dich in deinem Deezer-Account anmelden bevor du mit dem Download starten kannst.',
openSettings: 'Einstellungen öffnen', openSettings: 'Einstellungen öffnen',
sections: { sections: {
popularPlaylists: 'Beliebte Playlisten', popularPlaylists: 'Beliebte Playlists',
popularAlbums: 'Meist gestreamte Alben' popularAlbums: 'Meistgestreamte Alben'
} }
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'In dieser Sektion findest du weitere Informationen über den Link, den du versuchst herunterzuladen.', info: 'Diesen Abschnitt kannst du nutzen, um weitere Informationen über den gewünschten Link zu erhalten, den du herunterladen möchtest.',
useful: useful: "Dies ist z.B. nützlich, wenn du versuchst einige Titel herunterzuladen, welche in deinem Land nicht verfügbar sind, und du wissen möchtest, wo sie verfügbar sind.",
"Dies ist nützlich, wenn du versuchst, einige Titel herunterzuladen, die in deinem Land nicht verfügbar sind, und du zum Beispiel wissen willst, wo sie verfügbar sind.",
linkNotSupported: 'Dieser Link wird noch nicht unterstützt', linkNotSupported: 'Dieser Link wird noch nicht unterstützt',
linkNotSupportedYet: 'Es scheint, als ob dieser Link noch nicht unterstützt wird, versuche einen anderen zu analysieren.', linkNotSupportedYet: 'Es scheint so, als ob dieser Link noch nicht unterstützt wird. Versuche einen anderen Link zu analysieren.',
table: { table: {
id: 'ID', id: 'ID',
isrc: 'ISRC', isrc: 'ISRC',
upc: 'UPC', upc: 'UPC',
duration: 'Länge', duration: 'Dauer',
diskNumber: 'Disk Nummer', diskNumber: 'CD Nummer',
trackNumber: 'Titel Nummer', trackNumber: 'Track Nummer',
releaseDate: 'Veröffentlichungsdatum', releaseDate: 'Veröffentlichungsdatum',
bpm: 'BPM', bpm: 'BPM',
label: 'Musiklabel', label: 'Label',
recordType: 'Record Typ', recordType: 'Art der Aufnahme',
genres: 'Genres', genres: 'Genres',
tracklist: 'Tracklist' tracklist: 'Trackliste'
} }
}, },
search: { search: {
startSearching: 'Suche starten!', startSearching: 'Suche starten!',
description: description: 'Du kannst einen Titel, ein ganzes Album, einen Künstler, eine Playlist suchen ... alles! Du kannst auch einen Deezer-Link einfügen',
'Du kannst einen Track suchen, ein ganzes Album, einen Künstler, eine Playlist.... alles! Du kannst auch einen Deezer-Link einfügen',
fans: '{0} Fans', fans: '{0} Fans',
noResults: 'Keine Ergebnisse', noResults: 'Keine Ergebnisse',
noResultsTrack: 'Keine Titel gefunden', noResultsTrack: 'Keine Tracks gefunden',
noResultsAlbum: 'Keine Alben gefunden', noResultsAlbum: 'Keine Alben gefunden',
noResultsArtist: 'Keine Künstler gefunden', noResultsArtist: 'Keinen Künstler gefunden',
noResultsPlaylist: 'Keine Playlisten gefunden' noResultsPlaylist: 'Keine Playlist gefunden'
}, },
searchbar: 'Suche alles, was du willst (oder füge einfach einen Link ein)', searchbar: 'Suche nach allem, was dir gefällt (oder füge einfach einen Link ein)',
downloads: 'downloads', downloads: 'Downloads',
toasts: { toasts: {
addedToQueue: '{0} zur Warteschlange hinzugefügt', addedToQueue: '{0} zur Warteschlange hinzugefügt',
alreadyInQueue: '{0} ist bereits in der Warteschlange!', alreadyInQueue: '{0} ist bereits in der Warteschlange!',
finishDownload: '{0} bereits heruntgeladen', finishDownload: '{0} vollständig heruntergeladen.',
allDownloaded: 'Alle Downloads abgeschlossen!', allDownloaded: 'Alle Downloads abgeschlossen!',
refreshFavs: 'Aktualisierung abgeschlossen!', refreshFavs: 'Abgeschlossene Downloads neu laden!',
loggingIn: 'Einloggen', loggingIn: 'Einloggen',
loggedIn: 'Eingeloggt', loggedIn: 'Eingeloggt',
alreadyLogged: 'Bereits eingeloggt', alreadyLogged: 'Bereits eingeloggt',
loginFailed: "Einloggen nicht möglich", loginFailed: "Login fehlgeschlagen",
loggedOut: 'Ausgeloggt', loggedOut: 'Ausgeloggt',
cancellingCurrentItem: 'Aktuellen Eintrag abbrechen.', cancellingCurrentItem: 'Aktuelle Auswahl abbrechen.',
currentItemCancelled: 'Aktueller Eintrag abgebrochen.', currentItemCancelled: 'Aktuelle Auswahl wurde abgebrochen',
startAddingArtist: '{0} Alben zur Warteschlange hinzufügen', startAddingArtist: '{0} Alben werden hinzugefügt',
finishAddingArtist: '{0} Alben zur Warteschlange hinzugefügt', finishAddingArtist: '{0} Alben wurden hinzugefügt',
startConvertingSpotifyPlaylist: 'Umwandlung von Spotify-Titel in Deezer-Titel', startConvertingSpotifyPlaylist: 'Konvertierern von Spotify-Tracks zu Deezer-Tracks',
finishConvertingSpotifyPlaylist: 'Spotify Playlist konvertiert' finishConvertingSpotifyPlaylist: 'Spotify Playlist convertiert'
}, },
settings: { settings: {
title: 'Eisntellungen', title: 'Einstellungen',
languages: 'Sprachen', languages: 'Sprachen',
login: { login: {
title: 'Login', title: 'Login',
loggedIn: 'Sie sind eingeloggt als {username}', loggedIn: 'Du bist eingeloggt als {username}',
arl: { arl: {
question: 'Wie bekomme ich meine eigene ARL?', question: 'Wie bekomme ich meine eigene ARL?',
update: 'ARL aktualisieren' update: 'Update ARL'
}, },
logout: 'Ausloggen' logout: 'Logout'
}, },
appearance: { appearance: {
title: 'Aussehen', title: 'Design',
slimDownloadTab: 'Schlanker Download-Tab' slimDownloadTab: 'schmaler Download-Tab'
}, },
downloadPath: { downloadPath: {
title: 'Download Pfad' title: 'Download Pfad'
}, },
templates: { templates: {
title: 'Vorlagen', title: 'Vorlagen',
tracknameTemplate: 'Titelname Vorlage', tracknameTemplate: 'Vorlage für den Tracknamen',
albumTracknameTemplate: 'Album Titel Vorlage', albumTracknameTemplate: 'Vorlage für Tracks in einem Album',
playlistTracknameTemplate: 'Playlist Titel Vorlage' playlistTracknameTemplate: 'Vorlage für Tracks in einer Playlist'
}, },
folders: { folders: {
title: 'Ordner', title: 'Folders',
createPlaylistFolder: 'Ordner für Playlists erstellen', createPlaylistFolder: 'Ordner für Playlist erstellen',
playlistNameTemplate: 'Vorlage für Playlist-Ordner', playlistNameTemplate: 'Vorlage für Playlist-Ordner',
createArtistFolder: 'Ordner für Künstler erstellen', createArtistFolder: 'Ordner für Künstler erstellen',
artistNameTemplate: 'Vorlage für Künstler-Ordner', artistNameTemplate: 'Vorlage für Künstler-Ordner',
createAlbumFolder: 'Ordner für Album erstellen', createAlbumFolder: 'Ordner für Album erstellen',
albumNameTemplate: 'Vorlage für Album-Ordner', albumNameTemplate: 'Vorlage für Album-Ordner',
createCDFolder: 'Ordner für CDs erstellen', createCDFolder: 'Ordner für CDs erstellen',
createStructurePlaylist: 'Ordnerstruktur für Wiedergabelisten erstellen', createStructurePlaylist: 'Erstellen von Künstler-, Alben- und CD-Ordnern auch für Playlists',
createSingleFolder: 'Ordnerstruktur für Singles erstellen' createSingleFolder: 'Ordner für einzelne Titel erstellen'
}, },
trackTitles: { trackTitles: {
title: 'Tracktitel', title: 'Songtitel',
padTracks: 'Pad tracks', padTracks: 'Einheitliche Länge der Titelnummern (voranstehende Nullen werden ergänzt)',
paddingSize: 'Overwrite padding size', paddingSize: 'Innenabstand überschreiben',
illegalCharacterReplacer: 'Unzulässiger Zeichen-Ersetzer' illegalCharacterReplacer: 'Unzulässige Zeichen ersetzen'
}, },
downloads: { downloads: {
title: 'Downloads', title: 'Downloads',
@ -213,131 +208,133 @@ const de = {
1: 'MP3 128kbps' 1: 'MP3 128kbps'
}, },
overwriteFile: { overwriteFile: {
title: 'Soll ich die Dateien überschreiben?', title: 'Soll ich die Dateien überchreiben?',
y: 'Ja, Datei überschreiben', y: 'Ja überschreibe die Dateien',
n: "Nein, Datei nicht überschreiben", n: 'Nein überschreibe die Dateien nicht',
t: 'Nur Tags überschreiben' t: 'Überschreibe nur die Tags',
b: 'Nein, behalte beide Dateien und füge der Kopie eine Nummer hinzu'
}, },
fallbackBitrate: 'Fallback Bitrate', fallbackBitrate: 'Falls gewünschte Bitrate nicht verfügbar, auf niedrigere Bitrate zurückgreifen',
fallbackSearch: 'Fallback suchen', fallbackSearch: 'Zur Suche zurückkehren, wenn der Song nicht verfügbar ist',
logErrors: 'Protokolldateien für Fehler erstellen', logErrors: 'Protokolldatei für Fehler im Download-Ordner erstellen',
logSearched: 'Protokolldateien für gesuchte Titel erstellen', logSearched: 'Protokolldatei für gesuchte Titel erstellen',
createM3U8File: 'Playlist-Datei erstellen (M3U8)', createM3U8File: 'Erstelle Playlist-Datei (M3U8)',
syncedLyrics: '.lyr-Dateien erstellen (Liedtexte synchronisieren)', syncedLyrics: 'Erstelle synchrone Lyrics-Datei (.lyr)',
playlistFilenameTemplate: 'Vorlage für Playlist-Dateinamen', playlistFilenameTemplate: 'Vorlage für den Namen der Playlist',
saveDownloadQueue: 'Speichern der Download-Warteschlange beim Schließen der Anwendung' saveDownloadQueue: 'Download-Warteschlange beim Schließen der App speichern'
}, },
covers: { covers: {
title: 'Album-Cover', title: 'Album Cover',
saveArtwork: 'Cover speichern', saveArtwork: 'Cover speichern',
coverImageTemplate: 'Vorlage für Cover-Bezeichnung', coverImageTemplate: 'Vorlage für den Covernamen',
saveArtworkArtist: 'Künstlerbild speichern', saveArtworkArtist: 'Speichere das Künstlerbild',
artistImageTemplate: 'Vorlage für Künstlerbild', artistImageTemplate: 'Vorlage des Künstlerbildes',
localArtworkSize: 'Lokale Größe des Künstlerbildes', localArtworkSize: 'Lokale Grafikgröße',
embeddedArtworkSize: 'Eingebettete Größe des Künstlerbildes', embeddedArtworkSize: 'Eingebettete Grafikgröße',
localArtworkFormat: { localArtworkFormat: {
title: 'Welches Format soll das lokale Künstlerbild haben?', title: 'Welches Datei-Format soll das Cover haben?',
jpg: 'Ein jpeg Bild', jpg: 'Ein jpg Bild',
png: 'Ein png Bild', png: 'Ein png Bild',
both: 'Beides, eine jpeg und eine png' both: 'Beides (jpg + png)'
}, },
jpegImageQuality: 'JPEG Bild Qualität' jpegImageQuality: 'JPEG Qualität'
}, },
tags: { tags: {
head: 'Welche Tags sollen gespeichert werden', head: 'Welche Tags sollen gespeichert werden?',
title: 'Titel', title: 'Titel',
artist: 'Künstler', artist: 'Künstler',
album: 'Album', album: 'Album',
cover: 'Cover', cover: 'Cover',
trackNumber: 'Titel Nummer', trackNumber: 'Titelnummer',
trackTotal: 'Titel Insgesamt', trackTotal: 'Titelanzahl',
discNumber: 'Disc Nummer', discNumber: 'CD Nummer',
discTotal: 'Disc Insgesamt', discTotal: 'CDs insgesamt',
albumArtist: 'Album Künstler', albumArtist: 'Album Künstler',
genre: 'Genre', genre: 'Genre',
year: 'Jahr', year: 'Jahr',
date: 'Datum', date: 'Datum',
explicit: 'Explizite Texte', explicit: 'Explizite Lyrics',
isrc: 'ISRC', isrc: 'ISRC',
length: 'Länge', length: 'Titel Länge',
barcode: 'Album Barcode (UPC)', barcode: 'Album Barcode (UPC)',
bpm: 'BPM', bpm: 'BPM',
replayGain: 'Replay Gain', replayGain: 'Wiedergabe Lautstärke',
label: 'Album Plattenlabel', label: 'Album Plattenlabel',
lyrics: 'Unsynchronisierte Liedtexte', lyrics: 'Nicht synchronisierte Texte',
copyright: 'Urheberrecht', copyright: 'Copyright',
composer: 'Komponist', composer: 'Komponist',
involvedPeople: 'Beteiligte Personen' involvedPeople: 'Mitwirkende Personen'
}, },
other: { other: {
title: 'Andere', title: 'Sonsitge',
savePlaylistAsCompilation: 'Wiedergabelisten als Compilation speichern', savePlaylistAsCompilation: 'Speichere Playlist als Zusammenstellung',
useNullSeparator: 'Null-Trennzeichen verwenden', useNullSeparator: 'Verwende Nulltrennzeichen',
saveID3v1: 'ID3v1 ebenfalls speichern', saveID3v1: 'Speichere ID3v1 ebenfalls',
multiArtistSeparator: { multiArtistSeparator: {
title: 'Wie möchten Sie Ihre Künstler trennen?', title: 'Wie möchtest du die Künstler trennen?',
nothing: 'Nur den Hauptkünstler speichern', nothing: 'Speichere nur den Hauptkünstler',
default: 'Verwendung der Standardspezifikation', default: 'Verwende Standard Spezifikationen',
andFeat: 'Verwendung von & und feat.', andFeat: 'Verwende & und feat.',
using: 'Verwendet "{0}"' using: 'Verwende "{0}"'
}, },
singleAlbumArtist: 'Nur den Interpreten des Hauptalbums speichern', singleAlbumArtist: 'Nur den Hauptkünstler speichern',
albumVariousArtists: '"Verschiedene Künstler" im Album Künstler Tag behalten', albumVariousArtists: 'Verschiedene Künstler" im Album Künstler Tag behalten',
removeAlbumVersion: '"Album-Version" aus dem Titelnamen entfernen', removeAlbumVersion: 'Entferne die "Album Version" vom Songtitel',
removeduplicateArtists: 'Kombinationen von Künstlern entfernen', removeDuplicateArtists: 'Kombinationen von Künstlern entfernen',
dateFormat: { dateFormat: {
title: 'Datumsformat für FLAC-Dateien', title: 'Datumsformatierung für FLAC Dateien',
year: 'YYYY', year: 'JJJJ',
month: 'MM', month: 'MM',
day: 'DD' day: 'TT'
}, },
featuredToTitle: { featuredToTitle: {
title: 'Was soll ich mit den Featured Künstlern machen?', title: 'Was soll ich mit featured Artists machen?',
0: 'Nichts', 0: 'Nichts',
1: 'Aus dem Titel entfernen', 1: 'Vom Titel entfernen',
3: 'Aus dem Titel und dem Albumtitel entfernen', 3: 'Vom Titel und Albumtitel entfernen',
2: 'In den Titel verschieben' 2: 'Zu dem Titel hinzufügen'
}, },
titleCasing: 'Titel Textformattierung', titleCasing: 'Titel-Schreibweise',
artistCasing: 'Künstler Textformattierung', artistCasing: 'Künstler-Schreibweise',
casing: { casing: {
nothing: 'Unverändert lassen', nothing: 'Unbearbeitet lassen',
lower: 'kleinbuchstaben', lower: 'klein',
upper: 'GROSSBUCHSTABEN', upper: 'GROSS',
start: 'Anfang Jedes Wortes', start: 'Wortanfang Gross',
sentence: 'Wie einen Satz' sentence: 'Satzanfang gross'
}, },
previewVolume: 'Vorschau Lautstärke', previewVolume: 'Vorschau der Lautstärke',
executeCommand: { executeCommand: {
title: 'Befehl zur Ausführung nach dem Download', title: 'Befehl, der nach dem Download ausgeführt werden soll',
description: 'Leer lassen für keine Aktion' description: 'Leer lassen ohne Aktion'
} }
}, },
spotify: { spotify: {
title: 'Spotify-Funktionen', title: 'Spotify Features',
clientID: 'Spotify clientID', clientID: 'Spotify Client ID',
clientSecret: 'Spotify Client Secret', clientSecret: 'Spotify Client Secret',
username: 'Spotify Benutzername' username: 'Spotify Benutzername'
}, },
reset: 'Auf Standard zurücksetzen', reset: 'Auf Standardwerte zurücksetzen',
save: 'Speichern', save: 'Speichern',
toasts: { toasts: {
init: 'Einstellungen geladen!', init: 'Einstellungen geladen!',
update: 'Einstellungen aktualisiert!', update: 'Einstellungen aktualisiert!',
ARLcopied: 'ARL in die Zwischenablage kopiert' ARLcopied: 'ARL wurde in die Zwischenablage kopiert'
} }
}, },
sidebar: { sidebar: {
home: 'start', home: 'Home',
search: 'suche', search: 'Suche',
charts: 'charts', charts: 'Charts',
favorites: 'favoriten', favorites: 'Favoriten',
linkAnalyzer: 'link-analysator', linkAnalyzer: 'Link Analyse',
settings: 'einstellungen', settings: 'Einstellungen',
about: 'über' about: 'Info'
}, },
tracklist: { tracklist: {
downloadSelection: 'Auswahl herunterladen' downloadSelection: 'Downloads'
} }
} }

View File

@ -11,6 +11,13 @@ const en = {
toggle_download_tab_hint: 'Expand/Collapse', toggle_download_tab_hint: 'Expand/Collapse',
clean_queue_hint: 'Clear Finished', clean_queue_hint: 'Clear Finished',
cancel_queue_hint: 'Cancel All', cancel_queue_hint: 'Cancel All',
open_downloads_folder: 'Open Downloads Folder',
cut: 'cut',
copy: 'copy',
copyLink: 'copy link',
copyImageLink: 'copy image link',
copyDeezerLink: 'copy deezer link',
paste: 'paste',
listTabs: { listTabs: {
empty: '', empty: '',
all: 'all', all: 'all',
@ -25,6 +32,8 @@ const en = {
playlist: 'playlist | playlists', playlist: 'playlist | playlists',
compile: 'compilation | compilations', compile: 'compilation | compilations',
ep: 'ep | eps', ep: 'ep | eps',
more: 'More albums',
featured: 'Featured in',
spotifyPlaylist: 'spotify playlist | spotify playlists', spotifyPlaylist: 'spotify playlist | spotify playlists',
releaseDate: 'release date', releaseDate: 'release date',
error: 'error' error: 'error'
@ -51,9 +60,9 @@ const en = {
officialWebuiRepo: 'Official WebUI Repository', officialWebuiRepo: 'Official WebUI Repository',
officialSubreddit: 'Official Subreddit', officialSubreddit: 'Official Subreddit',
newsChannel: 'News Channel', newsChannel: 'News Channel',
questions: `If you have questions or problems with the app, search for a solution in the <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a> first. Then, if you don't find anything you can make a post with your issue on the subreddit.`, questions: `If you have questions or problems with the app, search for a solution on the <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a> first. Then, if you don't find anything you can make a post with your issue on the subreddit.`,
beforeReporting: `Before reporting a bug make sure you're running the latest version of the app and that what you want to report is actually a bug and not something that's wrong only on your end.`, beforeReporting: `Before reporting a bug make sure you're running the latest version of the app and that what you want to report is actually a bug and not something that's wrong only on your end.`,
beSure: `Make sure the bug is reproducible on another machines and also <strong>DO NOT</strong> report a bug if it's been already reported.`, beSure: `Make sure the bug is reproducible on other machines and also <strong>DO NOT</strong> report a bug if it's already been reported.`,
duplicateReports: 'Duplicate bug reports will be closed, so keep an eye out on that.', duplicateReports: 'Duplicate bug reports will be closed, so keep an eye out on that.',
dontOpenIssues: `<strong>DO NOT</strong> open issues for asking questions, there is a subreddit for that.`, dontOpenIssues: `<strong>DO NOT</strong> open issues for asking questions, there is a subreddit for that.`,
newUI: `If you're fluent in python you could try to make a new UI for the app using the base library, or fix bugs in the library with a pull request on the <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repo</a>.`, newUI: `If you're fluent in python you could try to make a new UI for the app using the base library, or fix bugs in the library with a pull request on the <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repo</a>.`,
@ -61,12 +70,10 @@ const en = {
otherLanguages: `If you're fluent in another programming language you could try to port deemix into other programming languages!`, otherLanguages: `If you're fluent in another programming language you could try to port deemix into other programming languages!`,
understandingCode: `You need help understanding the code? Just hit RemixDev up on Telegram or Reddit.`, understandingCode: `You need help understanding the code? Just hit RemixDev up on Telegram or Reddit.`,
contributeWebUI: `If you know Vue.js (JavaScript), HTML or CSS you could contribute to the <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`, contributeWebUI: `If you know Vue.js (JavaScript), HTML or CSS you could contribute to the <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`,
itsFree: `You shoud remember that <strong>this is a free project</strong> and <strong>you should support the artists you love</strong> before supporting the developers.`, itsFree: `You should remember that <strong>this is a free project</strong> and <strong>you should support the artists you love</strong> before supporting the developers.`,
notObligated: `Don't feel obligated to donate, I appreciate you anyway!`, notObligated: `Don't feel obligated to donate, I appreciate you anyway!`,
lincensedUnder: `This work is licensed under a lincensedUnder: `This work is licensed under the
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank" <a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GNU General Public License 3.0</a>.`
>GNU General Public License 3.0</a
>.`
}, },
charts: { charts: {
title: 'Charts', title: 'Charts',
@ -78,19 +85,19 @@ const en = {
ids: { ids: {
invalidURL: 'URL not recognized', invalidURL: 'URL not recognized',
unsupportedURL: 'URL not supported yet', unsupportedURL: 'URL not supported yet',
ISRCnotOnDeezer: 'Track ISRC is not available on deezer', ISRCnotOnDeezer: 'Track ISRC is not available on Deezer',
notYourPrivatePlaylist: "You can't download others private playlists.", notYourPrivatePlaylist: "You can't download others private playlists.",
spotifyDisabled: 'Spotify Features is not setted up correctly.', spotifyDisabled: 'Spotify Features is not setted up correctly.',
trackNotOnDeezer: 'Track not found on deezer!', trackNotOnDeezer: 'Track not found on Deezer!',
albumNotOnDeezer: 'Album not found on deezer!', albumNotOnDeezer: 'Album not found on Deezer!',
notOnDeezer: 'Track not available on Deezer!', notOnDeezer: 'Track not available on Deezer!',
notEncoded: 'Track not yet encoded!', notEncoded: 'Track not yet encoded!',
notEncodedNoAlternative: 'Track not yet encoded and no alternative found!', notEncodedNoAlternative: 'Track not yet encoded and no alternative found!',
wrongBitrate: 'Track not found at desired bitrate.', wrongBitrate: 'Track not found at desired bitrate.',
wrongBitrateNoAlternative: 'Track not found at desired bitrate and no alternative found!', wrongBitrateNoAlternative: 'Track not found at desired bitrate and no alternative found!',
no360RA: 'Track is not available in Reality Audio 360.', no360RA: 'Track is not available in Reality Audio 360.',
notAvailable: "Track not available on deezer's servers!", notAvailable: "Track not available on Deezer's servers!",
notAvailableNoAlternative: "Track not available on deezer's servers and no alternative found!" notAvailableNoAlternative: "Track not available on Deezer's servers and no alternative found!"
} }
}, },
favorites: { favorites: {
@ -109,9 +116,8 @@ const en = {
} }
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'You can use this section to find out more information about the link you are trying to download.', info: 'You can use this section to find more information about the link you are trying to download.',
useful: useful: "This is useful if you're trying to download some tracks that are not available in your country and want to know where they are available, for instance.",
"This is useful if you're trying to download some tracks that are not available in your country and want to know where they are available, for instance.",
linkNotSupported: 'This link is not yet supported', linkNotSupported: 'This link is not yet supported',
linkNotSupportedYet: 'Seems like this link is not yet supported, try analyzing another one.', linkNotSupportedYet: 'Seems like this link is not yet supported, try analyzing another one.',
table: { table: {
@ -131,8 +137,7 @@ const en = {
}, },
search: { search: {
startSearching: 'Start searching!', startSearching: 'Start searching!',
description: description: 'You can search a track, a whole album, an artist, a playlist.... everything! You can also paste a Deezer link',
'You can search a track, a whole album, an artist, a playlist.... everything! You can also paste a Deezer link',
fans: '{0} fans', fans: '{0} fans',
noResults: 'No results', noResults: 'No results',
noResultsTrack: 'No Tracks found', noResultsTrack: 'No Tracks found',
@ -143,12 +148,15 @@ const en = {
searchbar: 'Search anything you want (or just paste a link)', searchbar: 'Search anything you want (or just paste a link)',
downloads: 'downloads', downloads: 'downloads',
toasts: { toasts: {
restoringQueue: 'Restoring download queue...',
queueRestored: 'Download queue restored!',
addedToQueue: '{0} added to queue', addedToQueue: '{0} added to queue',
addedMoreToQueue: '{0} items added to queue',
alreadyInQueue: '{0} is already in queue!', alreadyInQueue: '{0} is already in queue!',
finishDownload: '{0} finished downloading.', finishDownload: '{0} finished downloading.',
allDownloaded: 'All downloads completed!', allDownloaded: 'All downloads completed!',
refreshFavs: 'Refresh completed!', refreshFavs: 'Refresh completed!',
loggingIn: 'Logging in', loggingIn: 'Logging in...',
loggedIn: 'Logged in', loggedIn: 'Logged in',
alreadyLogged: 'Already logged in', alreadyLogged: 'Already logged in',
loginFailed: "Couldn't log in", loginFailed: "Couldn't log in",
@ -157,8 +165,9 @@ const en = {
currentItemCancelled: 'Current item cancelled.', currentItemCancelled: 'Current item cancelled.',
startAddingArtist: 'Adding {0} albums to queue', startAddingArtist: 'Adding {0} albums to queue',
finishAddingArtist: 'Added {0} albums to queue', finishAddingArtist: 'Added {0} albums to queue',
startConvertingSpotifyPlaylist: 'Converting spotify tracks to deezer tracks', startConvertingSpotifyPlaylist: 'Converting spotify tracks to Deezer tracks',
finishConvertingSpotifyPlaylist: 'Spotify playlist converted' finishConvertingSpotifyPlaylist: 'Spotify playlist converted',
loginNeededToDownload: 'You need to log in to download tracks!'
}, },
settings: { settings: {
title: 'Settings', title: 'Settings',
@ -216,7 +225,9 @@ const en = {
title: 'Should I overwrite the files?', title: 'Should I overwrite the files?',
y: 'Yes, overwrite the file', y: 'Yes, overwrite the file',
n: "No, don't overwrite the file", n: "No, don't overwrite the file",
t: 'Overwrite only the tags' t: 'Overwrite only the tags',
b: 'No, keep both files and add a number to the duplicate',
e: "No, and don't look at the extensions"
}, },
fallbackBitrate: 'Bitrate fallback', fallbackBitrate: 'Bitrate fallback',
fallbackSearch: 'Search fallback', fallbackSearch: 'Search fallback',
@ -241,7 +252,10 @@ const en = {
png: 'A png image', png: 'A png image',
both: 'Both a jpeg and a png' both: 'Both a jpeg and a png'
}, },
jpegImageQuality: 'JPEG image quality' jpegImageQuality: 'JPEG image quality',
embeddedArtworkPNG: 'Save embedded artwork as PNG',
embeddedPNGWarning: 'PNGs are not officialy supported by Deezer and can be buggy',
imageSizeWarning: 'Anything above x1200 is not officialy used by Deezer, you may encounter issues'
}, },
tags: { tags: {
head: 'Which tags to save', head: 'Which tags to save',
@ -315,9 +329,9 @@ const en = {
}, },
spotify: { spotify: {
title: 'Spotify Features', title: 'Spotify Features',
clientID: 'Spotify clientID', clientID: 'Spotify ClientID',
clientSecret: 'Spotify Client Secret', clientSecret: 'Spotify Client Secret',
username: 'Spotify username' username: 'Spotify Username'
}, },
reset: 'Reset to Default', reset: 'Reset to Default',
save: 'Save', save: 'Save',

View File

@ -11,6 +11,13 @@ const es = {
toggle_download_tab_hint: 'Expandir/Colapsar', toggle_download_tab_hint: 'Expandir/Colapsar',
clean_queue_hint: 'Limpiar terminados', clean_queue_hint: 'Limpiar terminados',
cancel_queue_hint: 'Cancelar todos', cancel_queue_hint: 'Cancelar todos',
open_downloads_folder: 'Abrir carpeta de descargas',
cut: 'cortar',
copy: 'copiar',
copyLink: 'copiar link',
copyImageLink: 'copiar link de la imagen',
copyDeezerLink: 'copiar link de Deezer',
paste: 'pegar',
listTabs: { listTabs: {
empty: '', empty: '',
all: 'todos', all: 'todos',
@ -25,6 +32,8 @@ const es = {
playlist: 'lista de reproducción | listas de reproducción', playlist: 'lista de reproducción | listas de reproducción',
compile: 'compilación | compilaciones', compile: 'compilación | compilaciones',
ep: 'ep | eps', ep: 'ep | eps',
more: 'Más álbumes',
featured: 'Apareció en',
spotifyPlaylist: 'lista de reproducción spotify | listas de reproducción spotify', spotifyPlaylist: 'lista de reproducción spotify | listas de reproducción spotify',
releaseDate: 'fecha de publicación', releaseDate: 'fecha de publicación',
error: 'error' error: 'error'
@ -65,8 +74,7 @@ const es = {
itsFree: `Debes recordar que <strong>este es un proyecto libre</fuerte> y <strong>debes apoyar a los artistas que amas</fuerte> antes de apoyar a los desarrolladores.`, itsFree: `Debes recordar que <strong>este es un proyecto libre</fuerte> y <strong>debes apoyar a los artistas que amas</fuerte> antes de apoyar a los desarrolladores.`,
notObligated: `No te sientas obligado a donar, ¡te aprecio de todas formas!`, notObligated: `No te sientas obligado a donar, ¡te aprecio de todas formas!`,
lincensedUnder: `Esta obra está autorizada bajo una lincensedUnder: `Esta obra está autorizada bajo una
<a rel="licencia" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank" <a rel="licencia" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GNU Licencia Pública General 3.0</a>.`
>GNU Licencia Pública General 3.0</a>.`
}, },
charts: { charts: {
title: 'Tablas', title: 'Tablas',
@ -87,12 +95,10 @@ const es = {
notEncoded: '¡Pista aún no codificada!', notEncoded: '¡Pista aún no codificada!',
notEncodedNoAlternative: '¡Pista aún no codificada y no se ha encontrado ninguna alternativa!', notEncodedNoAlternative: '¡Pista aún no codificada y no se ha encontrado ninguna alternativa!',
wrongBitrate: 'La pista no se encuentra a la velocidad de bitrate deseada.', wrongBitrate: 'La pista no se encuentra a la velocidad de bitrate deseada.',
wrongBitrateNoAlternative: wrongBitrateNoAlternative: '¡Pista no encontrada a la tasa de bits deseada y no se ha encontrado ninguna alternativa!',
'¡Pista no encontrada a la tasa de bits deseada y no se ha encontrado ninguna alternativa!',
no360RA: 'La pista no está disponible en Reality Audio 360.', no360RA: 'La pista no está disponible en Reality Audio 360.',
notAvailable: '¡La pista no está disponible en los servidores de Deezer!', notAvailable: '¡La pista no está disponible en los servidores de Deezer!',
notAvailableNoAlternative: notAvailableNoAlternative: '¡La pista no está disponible en los servidores de Deezer y no se ha encontrado ninguna alternativa!'
'¡La pista no está disponible en los servidores de Deezer y no se ha encontrado ninguna alternativa!'
} }
}, },
favorites: { favorites: {
@ -112,8 +118,7 @@ const es = {
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'Puedes usar esta sección para encontrar más información sobre el enlace que estás tratando de descargar.', info: 'Puedes usar esta sección para encontrar más información sobre el enlace que estás tratando de descargar.',
useful: useful: 'Esto es útil si está tratando de descargar algunas pistas que no están disponibles en su país y quiere saber dónde están disponibles, por ejemplo.',
'Esto es útil si está tratando de descargar algunas pistas que no están disponibles en su país y quiere saber dónde están disponibles, por ejemplo.',
linkNotSupported: 'Este enlace aún no está soportado', linkNotSupported: 'Este enlace aún no está soportado',
linkNotSupportedYet: 'Parece que este enlace aún no está soportado, intenta analizar otro.', linkNotSupportedYet: 'Parece que este enlace aún no está soportado, intenta analizar otro.',
table: { table: {
@ -133,8 +138,7 @@ const es = {
}, },
search: { search: {
startSearching: '¡Comienza a buscar!', startSearching: '¡Comienza a buscar!',
description: description: 'Puedes buscar un tema, un álbum entero, un artista, una lista de reproducción... ¡todo! También puedes pegar un enlace de Deezer',
'Puedes buscar un tema, un álbum entero, un artista, una lista de reproducción... ¡todo! También puedes pegar un enlace de Deezer',
fans: '{0} fanáticos', fans: '{0} fanáticos',
noResults: 'No hay resultados', noResults: 'No hay resultados',
noResultsTrack: 'No se encontraron pistas', noResultsTrack: 'No se encontraron pistas',
@ -145,7 +149,10 @@ const es = {
searchbar: 'Busca lo que quieras (o simplemente pega un enlace)', searchbar: 'Busca lo que quieras (o simplemente pega un enlace)',
downloads: 'descargas', downloads: 'descargas',
toasts: { toasts: {
restoringQueue: 'Restaurando cola de descarga...',
queueRestored: '¡Cola de descarga restaurada!',
addedToQueue: '{0} añadidos a la cola', addedToQueue: '{0} añadidos a la cola',
addedMoreToQueue: '{0} elementos añadidos a la cola',
alreadyInQueue: '¡{0} ya está en la cola!', alreadyInQueue: '¡{0} ya está en la cola!',
finishDownload: '{0} terminado de descargar.', finishDownload: '{0} terminado de descargar.',
allDownloaded: '¡Todas las descargas se han completado!', allDownloaded: '¡Todas las descargas se han completado!',
@ -160,7 +167,8 @@ const es = {
startAddingArtist: 'Añadiendo {0} álbumes a la cola', startAddingArtist: 'Añadiendo {0} álbumes a la cola',
finishAddingArtist: 'Añadido {0} álbumes a la cola', finishAddingArtist: 'Añadido {0} álbumes a la cola',
startConvertingSpotifyPlaylist: 'Convertir las pistas de Spotify en pistas de Deezer', startConvertingSpotifyPlaylist: 'Convertir las pistas de Spotify en pistas de Deezer',
finishConvertingSpotifyPlaylist: 'Lista de reproducción de Spotify convertida' finishConvertingSpotifyPlaylist: 'Lista de reproducción de Spotify convertida',
loginNeededToDownload: '¡Necesitas iniciar sesión para descargar títulos!'
}, },
settings: { settings: {
title: 'Configuración', title: 'Configuración',
@ -170,7 +178,7 @@ const es = {
loggedIn: 'Usted está conectado como {nombre de usuario}', loggedIn: 'Usted está conectado como {nombre de usuario}',
arl: { arl: {
question: '¿Cómo consigo mi propio ARL?', question: '¿Cómo consigo mi propio ARL?',
update: 'Actualizar la ARL' update: 'Actualiza la ARL'
}, },
logout: 'Cerrar sesión' logout: 'Cerrar sesión'
}, },
@ -218,7 +226,8 @@ const es = {
title: '¿Desea que sobreescriba los archivos?', title: '¿Desea que sobreescriba los archivos?',
y: 'Sí, sobrescribir el archivo', y: 'Sí, sobrescribir el archivo',
n: 'No, no sobrescribir el archivo', n: 'No, no sobrescribir el archivo',
t: 'Sobrescribir sólo las etiquetas' t: 'Sobrescribir sólo las etiquetas',
b: 'No, mantener los dos archivos y agrega un número al archivo duplicado'
}, },
fallbackBitrate: 'La solución alternativa de bitrate', fallbackBitrate: 'La solución alternativa de bitrate',
fallbackSearch: 'Búsqueda de la segunda opción', fallbackSearch: 'Búsqueda de la segunda opción',
@ -243,7 +252,8 @@ const es = {
png: 'Una imagen png', png: 'Una imagen png',
both: 'Ambos, jpeg y png' both: 'Ambos, jpeg y png'
}, },
jpegImageQuality: 'Calidad de la imagen JPEG' jpegImageQuality: 'Calidad de la imagen JPEG',
imageSizeWarning: 'Nada por encima de x1200 no es usado oficialmente por Deezer, tú podrías encontrar inconvenientes'
}, },
tags: { tags: {
head: '¿Qué etiquetas guardar?', head: '¿Qué etiquetas guardar?',

View File

@ -7,10 +7,17 @@ const fr = {
by: 'par {0}', by: 'par {0}',
in: 'en {0}', in: 'en {0}',
download_hint: 'Télécharger', download_hint: 'Télécharger',
play_hint: 'Jouer', play_hint: 'Lire',
toggle_download_tab_hint: 'Agrandir/Réduire', toggle_download_tab_hint: 'Développer/Réduire',
clean_queue_hint: 'Effacer les tâches terminées', clean_queue_hint: 'Retirer Les Tâches Terminées',
cancel_queue_hint: 'Tout Annuler', cancel_queue_hint: 'Tout Annuler',
open_downloads_folder: 'Ouvrir Le Dossier De Téléchargements',
cut: 'couper',
copy: 'copier',
copyLink: 'copier le lien',
copyImageLink: "copier le lien de l'image",
copyDeezerLink: 'copier le lien deezer',
paste: 'coller',
listTabs: { listTabs: {
empty: '', empty: '',
all: 'tout', all: 'tout',
@ -20,137 +27,136 @@ const fr = {
single: 'single | singles', single: 'single | singles',
title: 'titre | titres', title: 'titre | titres',
track: 'piste | pistes', track: 'piste | pistes',
trackN: '0 pistes | {n} piste | {n} pistes', trackN: '0 piste | {n} piste | {n} pistes',
releaseN: '0 releases | {n} sortie | {n} sorties', releaseN: '0 parution | {n} parution | {n} parutions',
playlist: 'playlist | playlists', playlist: 'playlist | playlists',
compile: 'compilation | compilations', compile: 'compilation | compilations',
ep: 'ep | eps', ep: 'ep | eps',
more: "Plus d'albums",
featured: 'En vedette dans',
spotifyPlaylist: 'playlist spotify | playlists spotify', spotifyPlaylist: 'playlist spotify | playlists spotify',
releaseDate: 'date de sortie', releaseDate: 'date de parution',
error: 'erreur' error: 'erreur'
} }
}, },
about: { about: {
titles: { titles: {
usefulLinks: 'Liens Utiles', usefulLinks: 'Liens Utiles',
bugReports: 'Rapporter un Bug', bugReports: 'Rapports De Bug',
contributing: 'Contribuer', contributing: 'Contribution',
donations: 'Donations', donations: 'Dons',
license: 'Licence' license: 'Licence'
}, },
subtitles: { subtitles: {
bugReports: 'Y a-t-il quelque chose qui ne fonctionne pas avec deemix ? Dites-le nous !', bugReports: 'Y a-t-il quelque chose qui ne fonctionne pas dans deemix ? Dites-le nous !',
contributing: 'Vous souhaitez contribuer à ce projet ? Vous pouvez le faire de différentes manières !', contributing: 'Vous souhaitez contribuer à ce projet ? Vous pouvez le faire de différentes manières !',
donations: 'Vous souhaitez contribuer financièrement ? Vous pourriez faire un don !' donations: 'Vous souhaitez contribuer financièrement ? Vous pouvez faire un don !'
}, },
usesLibrary: usesLibrary: 'Cette application utilise la bibliothèque <strong>deemix</strong>, que vous pouvez exploiter afin de créer votre propre interface utilisateur pour deemix.',
'Cette application utilise la librairie <strong>deemix</strong>, que vous pouvez utiliser afin de créer votre propre interface utilisateur pour deemix.', thanks: "Merci à <strong>rtonno</strong>, <strong>uhwot</strong> et <strong>lollilol</strong> de m'avoir aidé dans ce projet ainsi qu'à <strong>BasCurtiz</strong> et <strong>scarvimane</strong> pour avoir réalisé l'icône.",
thanks: `Merci à <strong>rtonno</strong>, <strong>uhwot</strong> et <strong>lollilol</strong> pour m'avoir aidé avec ce projet et à <strong>BasCurtiz</strong> et <strong>scarvimane</strong> pour avoir réalisé l'icône.`, upToDate: 'Restez informé des mises à jour en suivant le <a href="https://t.me/RemixDevNews" target="_blank">canal de nouveautés</a> sur Telegram.',
upToDate: `Restez informé des mises à jour en suivant le <a href="https://t.me/RemixDevNews" target="_blank">canal d'information</a> sur Telegram.`,
officialWebsite: 'Site Officiel', officialWebsite: 'Site Officiel',
officialRepo: 'Site Officiel de la Librairie', officialRepo: 'Répertoire De Dépôt Officiel De La Bibiliothèque',
officialWebuiRepo: 'Site Officiel de WebUI', officialWebuiRepo: 'Répertoire De Dépôt Officiel De La WebUI',
officialSubreddit: 'Subreddit Officiel', officialSubreddit: 'Subreddit Officiel',
newsChannel: `Canal d'informations`, newsChannel: 'Canal De Nouveautés',
questions: `Si vous avez des questions ou soucis avec l'application, cherchez une solution sur le <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a> d'abord. Ensuite, vous pouvez créer une publication sur le subreddit en décrivant votre problème.`, questions: `Si vous avez des questions ou des problèmes avec l'application, cherchez d'abord une solution dans le <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a>. Ensuite, si vous ne trouvez rien, vous pouvez publier un message avec votre problème dans le subreddit.`,
beforeReporting: `Avant de rapporter un bug, assurez vous d'avoir la dernière version de l'application et que ce que vous voulez rapporter est bien un bug et non pas quelque chose qui ne fonctionne pas juste pour vous.`, beforeReporting: "Avant de signaler un bug, assurez-vous que vous exécutez la dernière version de l'application et que ce que vous voulez signaler est bien un bug et non quelque chose qui ne va pas de votre côté.",
beSure: `Assurez vous que le bug est reproductible sur d'autres machines et <strong>NE PAS</strong> rapporter un bug si il l'est déjà par quelqu'un d'autre.`, beSure: "Assurez-vous que le bug est reproductible sur d'autres machines et aussi de <strong>NE PAS</strong> signaler un bug si celui-ci a déjà été mentionné.",
duplicateReports: 'Les doublons de rapports de bug seront fermés, gardez un œil sur cela.', duplicateReports: 'Les doublons de rapports de bug seront supprimés, alors gardez un œil sur cela.',
dontOpenIssues: `<strong>NE PAS</strong> ouvrir un problème pour poser des questions, il y a un subreddit pour cela.`, dontOpenIssues: "<strong>NE PAS</strong> ouvrir un nouveau problème pour poser des questions, il existe un subreddit pour cela.",
newUI: `Si vous maitrisez le python, vous pourriez essayer de créer une nouvelle interface utilisateur pour l'application à l'aide de la librairie de base, ou corriger des bugs de cette librairie sur son <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repo git</a>.`, newUI: `Si vous maîtrisez python, vous pouvez essayer de créer une nouvelle interface utilisateur pour l'application à l'aide de la bibliothèque de base, ou corriger des bugs dans la bibliothèque à l'aide d'une demande de fusion de branches (pull request) sur le <a href="https://codeberg.org/RemixDev/deemix" target="_blank">répertoire de dépôt</a>.`,
acceptFeatures: `J'accepte également de nouvelles fonctionnalités, mais pas de choses complexes, car elles peuvent être implémentées directement dans l'application et non dans la librairie.`, acceptFeatures: "J'accepte également les fonctionnalités, mais pas de choses complexes, car elles peuvent être implémentées directement dans l'application et non dans la bibliothèque.",
otherLanguages: `Si vous maîtrisez un autre langage de programmation, vous pouvez essayer de porter deemix dans d'autres langages de programmation !`, otherLanguages: "Si vous maîtrisez un autre langage de programmation, vous pouvez essayer de transposer deemix dans d'autres langages de programmation !",
understandingCode: `Vous avez besoin d'aide pour comprendre le code ? Contactez RemixDev sur Telegram ou Reddit.`, understandingCode: "Vous avez besoin d'aide pour comprendre le code ? Il suffit de contacter RemixDev sur Telegram ou Reddit.",
contributeWebUI: `Si vous vous y connaissez en Vue.js (JavaScript), HTML ou CSS vous pourriez contribuer au <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`, contributeWebUI: `Si vous vous y connaissez en Vue.js (JavaScript), HTML ou CSS vous pouvez contribuer à la <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`,
itsFree: `N'oubliez pas que <strong>ce projet est gratuit</strong> et que <strong>vous devriez soutenir les artistes que vous aimez</strong> avant de supporter les développeurs.`, itsFree: "N'oubliez pas que <strong>ceci est un projet gratuit</strong> et que <strong>vous devez soutenir les artistes que vous appréciez</strong> avant de supporter les développeurs.",
notObligated: `Ne vous sentez pas obligé de faire un don, je vous apprécie quand même !`, notObligated: "Ne vous sentez pas obligé de faire un don, je vous apprécie quand même !",
lincensedUnder: `Ce projet est fourni sous la lincensedUnder: `Ce projet est autorisé dans le cadre d'une
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank" <a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.fr.html" target="_blank">Licence publique générale GNU 3.0</a>.`
>Licence publique générale GNU 3.0</a
>.`
}, },
charts: { charts: {
title: 'Classements', title: 'Hit-Parade',
changeCountry: 'Changer le Pays', changeCountry: 'Changer De Pays',
download: 'Télécharger le Classement' download: 'Télécharger Le Hit-Parade'
}, },
errors: { errors: {
title: 'Erreurs pour {0}', title: 'Erreurs pour {0}',
ids: { ids: {
invalidURL: 'URL non reconnue', invalidURL: "Cette URL n'est pas reconnue",
unsupportedURL: 'URL pas encore prise en charge', unsupportedURL: "Cette URL n'est pas supportée actuellement",
ISRCnotOnDeezer: "L'ISRC de la piste n'est pas encore disponible sur deezer", ISRCnotOnDeezer: "L'ISRC de la piste est indisponible sur Deezer",
notYourPrivatePlaylist: "Vous ne pouvez pas télécharger les playlists privées de quelqu'un d'autre.", notYourPrivatePlaylist: "Vous ne pouvez pas télécharger les playlists privées de quelqu'un d'autre.",
spotifyDisabled: 'Les Fonctionnalités Spotify ne sont pas bien configurées.', spotifyDisabled: 'Les Fonctionnalités Spotify ne sont pas configurées correctement.',
trackNotOnDeezer: 'Piste introuvable sur deezer !', trackNotOnDeezer: 'La piste est introuvable sur Deezer !',
albumNotOnDeezer: 'Album introuvable sur deezer !', albumNotOnDeezer: "L'album est introuvable sur Deezer !",
notOnDeezer: 'Piste non disponible sur Deezer !', notOnDeezer: 'La piste est indisponible sur Deezer !',
notEncoded: 'Piste pas encore encodée !', notEncoded: "La piste n'a pas encore été encodée !",
notEncodedNoAlternative: 'Piste pas encore encodée et aucune alternative trouvée !', notEncodedNoAlternative: "La piste n'a pas encore été encodée et aucune alternative n'a été trouvée !",
wrongBitrate: 'Piste introuvable au débit souhaité.', wrongBitrate: 'La piste est introuvable au débit souhaité.',
wrongBitrateNoAlternative: 'Piste introuvable au débit souhaité et aucune alternative trouvée !', wrongBitrateNoAlternative: "La piste est introuvable au débit souhaité et aucune alternative n'a été trouvée !",
no360RA: "La piste n'est pas disponible avec Reality Audio 360.", no360RA: 'La piste est indisponible au format Reality Audio 360.',
notAvailable: 'Piste non disponible sur les serveurs de deezer !', notAvailable: 'La piste est indisponible sur les serveurs de Deezer !',
notAvailableNoAlternative: 'Piste non disponible sur les serveurs de deezer et aucune alternative trouvée !' notAvailableNoAlternative: "La piste est indisponible sur les serveurs de Deezer et aucune alternative n'a été trouvée !"
} }
}, },
favorites: { favorites: {
title: 'Favoris', title: 'Favoris',
noPlaylists: 'Aucune Playlist trouvée', noPlaylists: "Aucune Playlist n'a été trouvée",
noAlbums: 'Aucuns Album Favori trouvé', noAlbums: "Aucun Album Favori n'a été trouvé",
noArtists: 'Aucun Artiste Favori trouvé', noArtists: "Aucun Artiste Favori n'a été trouvé",
noTracks: 'Aucune Piste Favorite trouvée' noTracks: "Aucune Piste Favorite n'a été trouvée"
}, },
home: { home: {
needTologin: 'Vous devez vous connecter à votre compte Deezer avant de pouvoir commencer le téléchargement.', needTologin: 'Vous devez vous connecter à votre compte Deezer avant de pouvoir commencer les téléchargements.',
openSettings: 'Ouvrir les Paramètres', openSettings: 'Ouvrir Les Paramètres',
sections: { sections: {
popularPlaylists: 'Playlists Populaires', popularPlaylists: 'Playlists populaires',
popularAlbums: 'Albums les plus diffusés' popularAlbums: 'Albums les plus diffusés'
} }
}, },
linkAnalyzer: { linkAnalyzer: {
info: info: "Vous pouvez utiliser cette section pour obtenir plus d'informations sur le lien que vous essayez de télécharger.",
"Vous pouvez utiliser cette section afin de trouver plus d'informations sur le lien que vous essayer de télcharger.", useful: "C'est utile si vous essayer de télécharger des pistes qui ne sont pas disponibles dans votre pays et que vous souhaitez savoir où elles sont disponibles, par exemple.",
useful: linkNotSupported: "Ce lien n'est pas encore pris en charge",
"C'est utile si vous essayer de télécharger des pistes qui ne sont pas disponibles dans votre pays et que vous souhaitez savoir où elles sont disponibles, par exemple.", linkNotSupportedYet: "Il semble que ce lien ne soit pas encore pris en charge, essayez d'en analyser un autre.",
linkNotSupported: "Ce lien n'est pas encore supporté",
linkNotSupportedYet: 'Seems like this link is not yet supported, try analyzing another one.',
table: { table: {
id: 'ID', id: 'ID',
isrc: 'ISRC', isrc: 'ISRC',
upc: 'UPC', upc: 'UPC',
duration: 'Durée', duration: 'Durée',
diskNumber: 'Numéro de Disque', diskNumber: 'Numéro De Disque',
trackNumber: 'Numéro de Piste', trackNumber: 'Numéro De Disque',
releaseDate: 'Date de Sortie', releaseDate: 'Date De Parution',
bpm: 'BPM', bpm: 'BPM',
label: 'Label', label: 'Label',
recordType: "Type d'Enregistrement", recordType: "Type d'Enregistrement",
genres: 'Genres', genres: 'Genres',
tracklist: 'Tracklist' tracklist: 'Liste Des Pistes'
} }
}, },
search: { search: {
startSearching: 'Lancer la recherche !', startSearching: 'Commencer une recherche !',
description: description: 'Vous pouvez rechercher une piste, un album entier, un artiste, une playlist... tout ! Vous pouvez également copier-coller un lien Deezer',
'Vous pouvez rechercher une piste, un album entier, un artiste, une playlist .... tout ! Vous pouvez également copier-coller un lien Deezer',
fans: '{0} fans', fans: '{0} fans',
noResults: 'Aucun résultat', noResults: 'Aucun résultat',
noResultsTrack: 'Aucune Piste trouvée', noResultsTrack: "Aucune piste n'a été trouvée",
noResultsAlbum: 'Aucun Album trouvé', noResultsAlbum: "Aucun album n'a été trouvé",
noResultsArtist: 'Aucun Artiste trouvé', noResultsArtist: "Aucun artiste n'a été trouvé",
noResultsPlaylist: 'Aucune Playlist trouvée' noResultsPlaylist: "Aucune playlist n'a été trouvée"
}, },
searchbar: 'Recherchez tout ce que vous voulez (ou copier-collez un lien)', searchbar: 'Recherchez tout ce que vous voulez (ou copiez-collez simplement un lien)',
downloads: 'téléchargements', downloads: 'téléchargements',
toasts: { toasts: {
restoringQueue: "Restauration de la file d'attente de téléchargement...",
queueRestored: "La file d'attente de téléchargement a été restaurée !",
addedToQueue: "{0} ajouté à la file d'attente", addedToQueue: "{0} ajouté à la file d'attente",
addedMoreToQueue: "{0} éléments ajoutés à la file d'attente",
alreadyInQueue: "{0} est déjà en file d'attente !", alreadyInQueue: "{0} est déjà en file d'attente !",
finishDownload: '{0} a fini de télécharger.', finishDownload: '{0} a été téléchargé.',
allDownloaded: 'Tous les téléchargements sont terminés !', allDownloaded: 'Tous les téléchargements sont terminés !',
refreshFavs: 'Actualisation terminée !', refreshFavs: 'Actualisation terminée !',
loggingIn: 'Connexion', loggingIn: 'Connexion...',
loggedIn: 'Connecté', loggedIn: 'Connecté',
alreadyLogged: 'Déjà connecté', alreadyLogged: 'Déjà connecté',
loginFailed: 'Connexion impossible', loginFailed: 'Connexion impossible',
@ -158,9 +164,10 @@ const fr = {
cancellingCurrentItem: "Annulation de l'élément actuel.", cancellingCurrentItem: "Annulation de l'élément actuel.",
currentItemCancelled: 'Élément actuel annulé.', currentItemCancelled: 'Élément actuel annulé.',
startAddingArtist: "Ajout de {0} albums en file d'attente", startAddingArtist: "Ajout de {0} albums en file d'attente",
finishAddingArtist: "Ajouté {0} en file d'attente", finishAddingArtist: "{0} albums ajoutés en file d'attente",
startConvertingSpotifyPlaylist: 'Converting spotify tracks to deezer tracks', startConvertingSpotifyPlaylist: 'Conversion de pistes Spotify en pistes Deezer',
finishConvertingSpotifyPlaylist: 'Spotify playlist converted' finishConvertingSpotifyPlaylist: 'Playlist Spotify convertie',
loginNeededToDownload: 'Vous devez vous connecter pour pouvoir télécharger des pistes !'
}, },
settings: { settings: {
title: 'Paramètres', title: 'Paramètres',
@ -169,41 +176,41 @@ const fr = {
title: 'Connexion', title: 'Connexion',
loggedIn: 'Vous êtes connecté en tant que {username}', loggedIn: 'Vous êtes connecté en tant que {username}',
arl: { arl: {
question: 'Comment obtenir mon propre ARL ?', question: 'Comment puis-je obtenir mon ARL personnel ?',
update: "Mettre à jour l'ARL" update: "Mettre à jour l'ARL"
}, },
logout: 'Déconnecter' logout: 'Déconnexion'
}, },
appearance: { appearance: {
title: 'Apparence', title: 'Apparence',
slimDownloadTab: 'Onglet de téléchargement mince' slimDownloadTab: 'Onglet de téléchargement plus petit'
}, },
downloadPath: { downloadPath: {
title: 'Dossier de Téléchargement' title: 'Emplacement De Téléchargement'
}, },
templates: { templates: {
title: 'Modèles', title: 'Gabarits',
tracknameTemplate: 'Modèle de nom de piste', tracknameTemplate: 'Gabarit pour le nom de piste',
albumTracknameTemplate: "Modèle de piste d'album", albumTracknameTemplate: "Gabarit pour le nom de piste de l'album",
playlistTracknameTemplate: 'Modèle de piste de playlist' playlistTracknameTemplate: 'Gabarit pour le nom de piste de la playlist'
}, },
folders: { folders: {
title: 'Dossiers', title: 'Dossiers',
createPlaylistFolder: 'Créer un dossier pour Playlists', createPlaylistFolder: 'Générer des dossiers par playlist',
playlistNameTemplate: 'Modèle de dossier pour Playlist', playlistNameTemplate: 'Gabarit pour le nom du dossier de playlist',
createArtistFolder: 'Créer un dossier pour Artiste', createArtistFolder: 'Générer des dossiers par artiste',
artistNameTemplate: 'Modèle de dossier pour Artiste', artistNameTemplate: "Gabarit pour le nom du dossier d'artiste",
createAlbumFolder: 'Créer un dossier pour Album', createAlbumFolder: 'Générer des dossiers par album',
albumNameTemplate: 'Modèle de dossier pour Album', albumNameTemplate: "Gabarit pour le nom du dossier d'album",
createCDFolder: 'Créer un dossier pour CDs', createCDFolder: 'Générer des dossiers par CD',
createStructurePlaylist: 'Créer une structure de dossiers pour Playlists', createStructurePlaylist: 'Créer une structure de dossiers pour les playlists',
createSingleFolder: 'Créer une structure de dossiers pour Singles' createSingleFolder: 'Créer une structure de dossiers pour les singles'
}, },
trackTitles: { trackTitles: {
title: 'Titres de pistes', title: 'Titres de pistes',
padTracks: 'Pad tracks', padTracks: "Longueur uniforme des numéros de piste (ajoute automatiquement des zéros devant le numéro initial de la piste)",
paddingSize: 'Écraser la taille du remplissage', paddingSize: 'Nombre de zéros à ajouter en permanance devant le numéro initial de la piste',
illegalCharacterReplacer: 'Caractère de remplacement illégal' illegalCharacterReplacer: 'Remplacement de caractère inapproprié'
}, },
downloads: { downloads: {
title: 'Téléchargements', title: 'Téléchargements',
@ -217,75 +224,80 @@ const fr = {
overwriteFile: { overwriteFile: {
title: 'Dois-je écraser les fichiers ?', title: 'Dois-je écraser les fichiers ?',
y: 'Oui, écraser le fichier', y: 'Oui, écraser le fichier',
n: "Non, n'écrasez pas le fichier", n: 'Non, ne pas écraser le fichier',
t: 'Écraser uniquement les balises' t: 'Écraser uniquement les métadonnées',
b: 'Non, conserver les deux fichiers et ajouter un numéro au doublon',
e: "Non, et ne pas tenir compte de l'extension du fichier"
}, },
fallbackBitrate: 'Débit de secours', fallbackBitrate: "Recourir à des débits plus faibles si le débit préféré n'est pas disponible",
fallbackSearch: 'Recherche de secours', fallbackSearch: "Rechercher la piste si le lien original n'est pas disponible",
logErrors: 'Créer des fichiers journaux pour les erreurs', logErrors: "Créer un fichier journal d'erreurs",
logSearched: 'Créer des fichiers journaux pour les pistes recherchées', logSearched: 'Créer un fichier journal des pistes recherchées',
createM3U8File: 'Créer un fichier playlist', createM3U8File: 'Créer un fichier de playlist',
syncedLyrics: 'Créer des fichiers .lyr (Sync Paroles)', syncedLyrics: 'Créer des fichiers .lyr (Paroles Synchronisées)',
playlistFilenameTemplate: 'Modèle de nom de fichier de Playlist', playlistFilenameTemplate: 'Gabarit du nom de fichier de la playlist',
saveDownloadQueue: "Enregistrer la file d'attente lors de la fermeture de l'application" saveDownloadQueue: "Enregistrer la file d'attente de téléchargement à la fermeture de l'application"
}, },
covers: { covers: {
title: "Couvertures d'album", title: "Pochettes d'albums",
saveArtwork: 'Enregistrer les couvertures', saveArtwork: 'Enregistrer Les Pochettes',
coverImageTemplate: 'Modèle de nom de la couverture', coverImageTemplate: 'Gabarit pour le nom de la pochette',
saveArtworkArtist: "Enregistrer l'image de l'artiste", saveArtworkArtist: "Enregistrer l'image de l'artiste",
artistImageTemplate: "Modèle de l'image de l'artiste", artistImageTemplate: "Gabarit pour le nom de l'image de l'artiste",
localArtworkSize: "Taille de l'illustration locale", localArtworkSize: "Taille de l'illustration locale",
embeddedArtworkSize: "Taille de l'illustration intégrée", embeddedArtworkSize: "Taille de l'illustration incorporée",
localArtworkFormat: { localArtworkFormat: {
title: "Dans quel format voulez-vous que l'illustration locale soit ?", title: "Dans quel format souhaitez-vous l'illustration locale ?",
jpg: 'Une image jpeg', jpg: 'Une image jpeg',
png: 'Une image png', png: 'Une image png',
both: 'Les deux, jpeg et png' both: 'À la fois jpeg et png'
}, },
jpegImageQuality: "Qualité d'image JPEG" jpegImageQuality: "Qualité de l'image JPEG",
embeddedArtworkPNG: "Enregistrer l'illustration incorporée en tant qu'image PNG",
embeddedPNGWarning: 'Les images PNG ne sont pas officiellement utilisées par Deezer et pourraient causer des problèmes',
imageSizeWarning: "Toute valeur supérieure à x1200 n'est pas officiellement utilisée par Deezer, vous pourriez donc rencontrer des problèmes"
}, },
tags: { tags: {
head: 'Balises à sauvegarder', head: 'Métadonnées à sauvegarder',
title: 'Titre', title: 'Titre',
artist: 'Artiste', artist: 'Artiste',
album: 'Album', album: 'Album',
cover: 'Couverture', cover: 'Pochette',
trackNumber: 'Numéro de Piste', trackNumber: 'Numéro De Piste',
trackTotal: 'Nombre de Pistes', trackTotal: 'Nombre De Pistes',
discNumber: 'Numéro du Disque', discNumber: 'Numéro Du Disque',
discTotal: 'Nombre de Disques', discTotal: 'Nombre De Disques',
albumArtist: "Artiste de l'Album", albumArtist: "Artiste De l'Album",
genre: 'Genre', genre: 'Genre',
year: 'Année', year: 'Année',
date: 'Date', date: 'Date',
explicit: 'Paroles Explicites', explicit: 'Paroles Explicites',
isrc: 'ISRC', isrc: 'ISRC',
length: 'Durée de Piste', length: 'Longueur De La Piste',
barcode: "Code-barres de l'album (UPC)", barcode: "Code-Barres De l'Album (UPC)",
bpm: 'BPM', bpm: 'BPM',
replayGain: 'Gain du Replay', replayGain: 'Gain En Relecture (Replay Gain)',
label: "Label de l'Album", label: "Label De l'Album",
lyrics: 'Paroles non synchronisées', lyrics: 'Paroles Non-Synchronisées',
copyright: "Droits d'auteur (copyright)", copyright: "Droits d'Auteur (Copyright)",
composer: 'Compositeur', composer: 'Compositeur',
involvedPeople: 'Personnes impliquées' involvedPeople: 'Personnes Impliquées'
}, },
other: { other: {
title: 'Autre', title: 'Autre',
savePlaylistAsCompilation: 'Enregistrer les playlists en tant que compilation', savePlaylistAsCompilation: 'Enregistrer les playlists en tant que compilation',
useNullSeparator: 'Utiliser un séparateur nul', useNullSeparator: 'Utiliser un séparateur nul',
saveID3v1: "Enregistrez l'ID3v1 également", saveID3v1: 'Enregistrer également les métadonnées ID3v1',
multiArtistSeparator: { multiArtistSeparator: {
title: 'Comment aimeriez-vous séparer vos artistes ?', title: 'Comment aimeriez-vous séparer les artistes ?',
nothing: "Enregistrer uniquement l'artiste principal", nothing: "Enregistrer uniquement l'artiste principal",
default: 'En utilisant la spécification standard', default: 'En utilisant la spécification standard',
andFeat: 'En utilisant & et feat.', andFeat: 'En utilisant & et feat.',
using: 'En utilisant "{0}"' using: 'En utilisant "{0}"'
}, },
singleAlbumArtist: "Enregistrer uniquement l'artiste principal de l'album", singleAlbumArtist: "Enregistrer uniquement l'artiste principal de l'album",
albumVariousArtists: `Conserver "Artistes Divers" dans les artistes de l'album`, albumVariousArtists: `Conserver "Various Artists" dans les Artistes de l'Album`,
removeAlbumVersion: `Supprimer "Version de l'album" du titre de la piste`, removeAlbumVersion: `Supprimer "Album Version" du titre de la piste`,
removeDuplicateArtists: "Supprimer les combinaisons d'artistes", removeDuplicateArtists: "Supprimer les combinaisons d'artistes",
dateFormat: { dateFormat: {
title: 'Format de date pour les fichiers FLAC', title: 'Format de date pour les fichiers FLAC',
@ -294,31 +306,31 @@ const fr = {
day: 'JJ' day: 'JJ'
}, },
featuredToTitle: { featuredToTitle: {
title: 'Que dois-je faire avec les artistes en vedette ?', title: 'Que dois-je faire avec les artistes participants (featuring) ?',
0: 'Rien', 0: 'Ne rien faire',
1: 'Retirez-les du titre', 1: 'Les retirer du titre de la piste',
3: "Supprimez-les du titre et du titre de l'album", 3: "Les supprimer du titre de la piste et du titre de l'album",
2: 'Déplacez-les vers le titre' 2: 'Les déplacer vers le titre de la piste'
}, },
titleCasing: 'Titre de la boîte', titleCasing: 'Casse pour le titre',
artistCasing: "Boite de l'artiste", artistCasing: "Casse pour l'artiste",
casing: { casing: {
nothing: 'Rester inchangé', nothing: 'Conserver inchangé',
lower: 'minuscule', lower: 'minuscules',
upper: 'MAJUSCULE', upper: 'MAJUSCULES',
start: 'Début De Chaque Mot', start: 'Majuscule Au Début De Chaque Mot',
sentence: 'Comme une phrase' sentence: 'Majuscule seulement au début de la phrase'
}, },
previewVolume: 'Aperçu du volume', previewVolume: 'Volume sonore des aperçus de pistes',
executeCommand: { executeCommand: {
title: 'Commande à exécuter après le téléchargement', title: 'Commande à exécuter après le téléchargement',
description: 'Laisser vide pour aucune action' description: "Laisser vide pour qu'aucune action n'ait lieu"
} }
}, },
spotify: { spotify: {
title: 'Fonctionnalités Spotify', title: 'Fonctionnalités Spotify',
clientID: 'ID Client Spotify', clientID: 'clientID Spotify',
clientSecret: 'Secret Client Spotify', clientSecret: 'Client Secret Spotify',
username: "Nom d'utilisateur Spotify" username: "Nom d'utilisateur Spotify"
}, },
reset: 'Rétablir les valeurs par défaut', reset: 'Rétablir les valeurs par défaut',
@ -331,15 +343,15 @@ const fr = {
}, },
sidebar: { sidebar: {
home: 'accueil', home: 'accueil',
search: 'chercher', search: 'recherche',
charts: 'classements', charts: 'hit-parade',
favorites: 'favoris', favorites: 'favoris',
linkAnalyzer: 'analyseur de liens', linkAnalyzer: 'analyseur de liens',
settings: 'paramètres', settings: 'paramètres',
about: 'à propos' about: 'à propos'
}, },
tracklist: { tracklist: {
downloadSelection: 'Section des téléchargements' downloadSelection: 'Télécharger la sélection'
} }
} }

346
src/lang/hr.js Normal file
View File

@ -0,0 +1,346 @@
const hr = {
globals: {
welcome: 'Dobrodošli u deemix',
back: 'nazad',
loading: 'učitavanje',
download: 'Preuzmi {0}',
by: 'by {0}',
in: 'u {0}',
download_hint: 'Preuzmi',
play_hint: 'Play',
toggle_download_tab_hint: 'Proširi/Smanji',
clean_queue_hint: 'Čišćenje završeno',
cancel_queue_hint: 'Zaustavi sve',
listTabs: {
empty: '',
all: 'sve',
top_result: 'Najbolji rezultat',
album: 'album | albumi',
artist: 'izvođač | izvođači',
single: 'singl | singlovi',
title: 'naslov | naslovi',
track: 'pjesma | pjesme',
trackN: '0 pjesmi | {n} pjesma | {n} pjesme',
releaseN: '0 izdanja | {n} izdanje | {n} izdanja',
playlist: 'playlista | playliste',
compile: 'kompilacija | kompilacije',
ep: 'ep | eps',
spotifyPlaylist: 'spotify playlista | spotify playliste',
releaseDate: 'datum izdavanja',
error: 'greška'
}
},
about: {
titles: {
usefulLinks: 'Korisne poveznice',
bugReports: 'Prijave grešaka',
contributing: 'Doprinosi',
donations: 'Donacije',
license: 'Licenca'
},
subtitles: {
bugReports: "Postoji nešto što ne radi u deemixu? Reci nam!",
contributing: 'Želiš doprinijeti ovom projektu? Možeš i to čak u više načina!',
donations: 'Želiš doprijeniti odmah? Možeš donirati!'
},
usesLibrary: 'Ova aplikacija koristi <strong>deemix</strong> biblioteku, koju možeš koristiti i ti kako bi napravio svoj UI za demix.',
thanks: `Hvala <strong>rtonno</strong>, <strong>uhwot</strong> i <strong>lollilol</strong> što su mi pomogli s ovim projektom te <strong>BasCurtiz</strong> i <strong>scarvimane</strong> što su napravili ikonu.`,
upToDate: `Ostani u tijeku s nadogradnjama prateći <a href="https://t.me/RemixDevNews" target="_blank">kanal s novostima</a> na Telegramu.`,
officialWebsite: 'Službena web stranica',
officialRepo: 'Službeni repozitorij biblioteke',
officialWebuiRepo: 'Službeni WebUI repozitorij',
officialSubreddit: 'Službeni subreddit',
newsChannel: 'Kanal s novostima',
questions: `Ukoliko imate pitanja o aplikaciji, prvo potražite riješenje na <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a>. Tada, ako ne pronađete ništa, možete objaviti svoj problem na subredditu.`,
beforeReporting: `Prije prijavljivanja greške provjerite imate li instaliranu zadnju verziju aplikacije i da to što želite prijaviti je ustvari pogreška, a ne nešto što samo vama ne radi.`,
beSure: `Provjerite može li se pogreška reproducirati i na drugim uređajima i također <strong>NEMOJTE</strong> prijavljivati grešku ako je već prijavljena.`,
duplicateReports: 'Duplicirane prijave o greški bit će zatvorene, tako da pripazite na to.',
dontOpenIssues: `<strong>NEMOJTE</strong> otvarati issue za postavljanje pitanja, za to postoji subreddit.`,
newUI: `Ako ste vješti u pythonu možete probati napraviti novi UI za aplikaciju koristeći osnovnu biblioteku ili ispraviti pogrešku u biblioteci sa pull zahtjevom na <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repozitoriju</a>.`,
acceptFeatures: `Prihavaćam i značajke, ali bez kompleksnih stvari, jer one mogu biti implementirane direktno u aplikaciji, a ne u biblioteci.`,
otherLanguages: `Ako ste vješti u drugom programskom jezikumožete probati portati deemix u drugi programski jezik!`,
understandingCode: `Trebate pomoć s razumijevanjem koda? Samo potraži RemixDev na Telegramu ili Redditu.`,
contributeWebUI: `Ako znaš Vue.js (JavaScript), HTML ili CSS možete doprinijeti za <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`,
itsFree: `Trebate zapamtiti da je ovo <strong>besplatni projekt</strong> i <strong>trebali biste podržati autore koje volite</strong> prije podržavanja developera.`,
notObligated: `Nemojte se osjećati obveznim darivati, svejedno vas cijenim!`,
lincensedUnder: `Ovaj rad licenciran je unutar
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"
>GNU General Public License 3.0</a
>.`
},
charts: {
title: 'Ljestvice',
changeCountry: 'Promijeni državu',
download: 'Preuzmi ljestvicu'
},
errors: {
title: 'Greške za {0}',
ids: {
invalidURL: 'URL nije prepoznat',
unsupportedURL: 'URL još nije podržan',
ISRCnotOnDeezer: 'Zapis ISRC još nije podržan na Deezeru',
notYourPrivatePlaylist: "Ne možete preuzeti tuđe privatne playliste.",
spotifyDisabled: 'Spotify značajke nisu podešene ispravno.',
trackNotOnDeezer: 'Pjesma nije pronađena na Deezeru!',
albumNotOnDeezer: 'Album nije pronađen na Deezeru!',
notOnDeezer: 'Pjesma nije dostupna na Deezeru!',
notEncoded: 'Pjesma još nije enkodirana!',
notEncodedNoAlternative: 'Pjesma još nije enkodirana i nije pronađena alternativa!',
wrongBitrate: 'Pjesma nije pronađena u željenom bitrateu.',
wrongBitrateNoAlternative: 'Pjesma nije pronađena u željenom bitrateu i nije pronađena alternativa!',
no360RA: 'Pjesma nije dostupna u Reality Audio 360.',
notAvailable: "Pjesma nije dostupna na Deezerovim serverima!",
notAvailableNoAlternative: "Pjesma nije dostupna na Deezerovim serverima i alternativa nije pronađena!"
}
},
favorites: {
title: 'Favoriti',
noPlaylists: 'Nisu pronađene playliste',
noAlbums: 'Omiljeni albumi nisu pronađeni',
noArtists: 'Omiljeni glazbenici nisu pronađeni',
noTracks: 'Omiljene pjesme nisu pronađene'
},
home: {
needTologin: 'Trebate se prijaviti sa svojim Deezer računom kako biste mogli početi preuzimati pjesme.',
openSettings: 'Otvori postavke',
sections: {
popularPlaylists: 'Popularne playliste',
popularAlbums: 'Najpreslušaniji album'
}
},
linkAnalyzer: {
info: 'Ovu sekciju možete koristiti kako biste saznali više informacija o linku koji pokušavate preuzeti.',
useful:
"Ovo je korisno ako pokušavate preuzeti pjesme koje još nisu dostupne u vašoj zemlji i želite, na primjer, znati gdje su dostupne.",
linkNotSupported: 'Ovaj link još nije podržan',
linkNotSupportedYet: 'Čini se da ovaj link još nije podržan, pokušaj analizirati neki drugi.',
table: {
id: 'ID',
isrc: 'ISRC',
upc: 'UPC',
duration: 'Trajanje',
diskNumber: 'Broj diska',
trackNumber: 'Broj pjesme',
releaseDate: 'Datum izadavanja',
bpm: 'BPM',
label: 'Izdavačka kuća',
recordType: 'Vrsta zapisa',
genres: 'Žanrovi',
tracklist: 'Popis pjesama'
}
},
search: {
startSearching: 'Počni pretraživati!',
description:
'Možete pretražiti pjesmu, cijeli album, izvođača, playlistu... sve! Također, možete i zalijepiti Deezer link',
fans: '{0} obožavatelja',
noResults: 'Nema rezultata',
noResultsTrack: 'Pjesme nisu pronađene',
noResultsAlbum: 'Albumi nisu pronađeni',
noResultsArtist: 'Izvođači nisu pronađeni',
noResultsPlaylist: 'Playliste nisu pronađene'
},
searchbar: 'Pretraži bilo što (ili samo zalijepi link)',
downloads: 'preuzimanja',
toasts: {
addedToQueue: '{0} dodan u red',
alreadyInQueue: '{0} je već u redu!',
finishDownload: '{0} završeno preuzimanje.',
allDownloaded: 'Sva preuzimanja završena!',
refreshFavs: 'Osvježavanje završeno!',
loggingIn: 'Prijavljivanje...',
loggedIn: 'Prijavljeni',
alreadyLogged: 'Već prijavljeni',
loginFailed: "Prijava nije bila moguća",
loggedOut: 'Odjavljeni',
cancellingCurrentItem: 'Otkazujem trenutnu stavku.',
currentItemCancelled: 'Trenutna stavka otkazana.',
startAddingArtist: 'Dodajem {0} album u red',
finishAddingArtist: 'Dodan {0} album u red',
startConvertingSpotifyPlaylist: 'Pretvaram Spotify pjesme u Deezer pjesme',
finishConvertingSpotifyPlaylist: 'Spotify playlista pretvorena',
loginNeededToDownload: 'Trebate se prijaviti kako bi preuzeli pjesme!'
},
settings: {
title: 'Postavke',
languages: 'Jezici',
login: {
title: 'Prijava',
loggedIn: 'Prijavljeni ste kao {username}',
arl: {
question: 'Kako da dobijem svoj ARL?',
update: 'Ažuriraj ARL'
},
logout: 'Odjavi se'
},
appearance: {
title: 'Izgled',
slimDownloadTab: 'Tanka kartica za preuzimanje'
},
downloadPath: {
title: 'Putanja za preuzimanja'
},
templates: {
title: 'Predlošci',
tracknameTemplate: 'Naziv pjesme predložak',
albumTracknameTemplate: 'Pjesma albuma predložak',
playlistTracknameTemplate: 'Pjesma playliste predložak'
},
folders: {
title: 'Mape',
createPlaylistFolder: 'Izradi mapu za playliste',
playlistNameTemplate: 'Mapa za playliste predložak',
createArtistFolder: 'Izradi mapu za izvođača',
artistNameTemplate: 'Izvođač mapa predložak',
createAlbumFolder: 'Izradi mapu za album',
albumNameTemplate: 'Album mapa predložak',
createCDFolder: 'Izradi mapu za CD',
createStructurePlaylist: 'Strkturiraj mape za playliste',
createSingleFolder: 'Strukturiraj mape za singlove'
},
trackTitles: {
title: 'Naslovi pjesama',
padTracks: 'Pad tracks',
paddingSize: 'Prepiši veličinu paddinga',
illegalCharacterReplacer: 'Zamjena za nedozvoljeni znak'
},
downloads: {
title: 'Preuzimanja',
queueConcurrency: 'Istovremena preuzimanja',
maxBitrate: {
title: 'Željeni bitrate',
9: 'FLAC 1411kbps',
3: 'MP3 320kbps',
1: 'MP3 128kbps'
},
overwriteFile: {
title: 'Trebam li prepisati datoteke?',
y: 'Da, prepiši datoteke',
n: "Ne, nemoj prepisati datoteke",
t: 'Prepiši samo oznake',
b: 'Ne, zadrži obje datoteke i dodaj broj duplikatu'
},
fallbackBitrate: 'Bitrate fallback',
fallbackSearch: 'Pretraživanje fallback',
logErrors: 'Izradi zapisnik datoteku za greške',
logSearched: 'Izradi zapisnik datoteku za pretražene pjesme',
createM3U8File: 'Izradi playlist datoteku',
syncedLyrics: 'Izradi .lyr datoteke (sinkronizirani lyrics)',
playlistFilenameTemplate: 'Naziv playliste predložak',
saveDownloadQueue: 'Spremi red za preuzimanje prilikom zatvaranja aplikacije'
},
covers: {
title: 'Omoti albuma',
saveArtwork: 'Spremi omote',
coverImageTemplate: 'Naziv omota predložak',
saveArtworkArtist: 'Spremi sliku izvođača',
artistImageTemplate: 'Slika izvođača predložak',
localArtworkSize: 'Veličina lokalnog omota',
embeddedArtworkSize: 'Veličina ugrađenog omota',
localArtworkFormat: {
title: 'U kojem formatu želite lokalni omot?',
jpg: 'Jpeg slika',
png: 'Png slika',
both: 'I jpeg i png'
},
jpegImageQuality: 'JPEG kvaliteta slike'
},
tags: {
head: 'Koja oznake spremam',
title: 'Naslovi',
artist: 'Izvođač',
album: 'Album',
cover: 'Omot',
trackNumber: 'Broj pjesme',
trackTotal: 'Ukupno pjesama',
discNumber: 'Broj diska',
discTotal: 'Ukupno diskova',
albumArtist: 'Izvođač albuma',
genre: 'Žanr',
year: 'Godina',
date: 'Datum',
explicit: 'Eksplicitni lyrics',
isrc: 'ISRC',
length: 'Dužina pjesme',
barcode: 'Album barkod (UPC)',
bpm: 'BPM',
replayGain: 'Replay Gain',
label: 'Izdavačka kuća albuma',
lyrics: 'Nesinkronizirani lyrics',
copyright: 'Autorska prava',
composer: 'Skladatelj',
involvedPeople: 'Uključeni ljudi'
},
other: {
title: 'Ostalo',
savePlaylistAsCompilation: 'Spremi playliste kao kompilacije',
useNullSeparator: 'Koristi null razdvojnik',
saveID3v1: 'Spremi i ID3v1 također',
multiArtistSeparator: {
title: 'Kako biste željeli razdvojiti izvođače?',
nothing: 'Spremi samo glavnog izvođača',
default: 'Koristeći standardnu specifikaciju',
andFeat: 'Koristeći & i feat.',
using: 'Koristeći "{0}"'
},
singleAlbumArtist: 'Spremi samo izvođača glavnog albuma',
albumVariousArtists: 'Zadrži "Various Artists" u Izvođačima albuma',
removeAlbumVersion: 'Izbriši "Album Version" iz naziva pjesme',
removeDuplicateArtists: 'Izbriši kombinacije izvođača',
dateFormat: {
title: 'Format datuma za FLAC datoteke',
year: 'YYYY',
month: 'MM',
day: 'DD'
},
featuredToTitle: {
title: 'Što trebam napraviti s istaknutim izvođačima? (feat. i ft.)',
0: 'Ništa',
1: 'Izbriši ih iz naziva',
3: 'Izbriši ih iz naziva i iz naziva albuma',
2: 'Premjesti ih u naziv'
},
titleCasing: 'Veličina slova naslova',
artistCasing: 'Veličina slova izvođača',
casing: {
nothing: 'Zadrži nepromijenjeno',
lower: 'sve malo',
upper: 'sve VELIKO',
start: 'Početak Svake Riječi',
sentence: 'Kao rečenica'
},
previewVolume: 'Volumen pregleda',
executeCommand: {
title: 'Naredba za izvršenje nakon preuzimanja',
description: 'Ostavi prazno za bez akcije'
}
},
spotify: {
title: 'Spotify značajke',
clientID: 'Spotify ClientID',
clientSecret: 'Spotify Client Secret',
username: 'Spotify korisničko ime'
},
reset: 'Resetiraj na zadano',
save: 'Spremi',
toasts: {
init: 'Postavke učitane!',
update: 'Postavke ažurirane!',
ARLcopied: 'ARL kopiran u međuspremnik'
}
},
sidebar: {
home: 'početna',
search: 'pretraživanje',
charts: 'ljestvice',
favorites: 'favoriti',
linkAnalyzer: 'analizator linka',
settings: 'postavke',
about: 'o programu'
},
tracklist: {
downloadSelection: 'Preuzmi selekciju'
}
}
export default hr

View File

@ -11,6 +11,13 @@ const it = {
toggle_download_tab_hint: 'Espandi/Riduci', toggle_download_tab_hint: 'Espandi/Riduci',
clean_queue_hint: 'Pulisci Lista', clean_queue_hint: 'Pulisci Lista',
cancel_queue_hint: 'Cancella tutti i download', cancel_queue_hint: 'Cancella tutti i download',
open_downloads_folder: 'Apri la cartella di download',
cut: 'taglia',
copy: 'copia',
copyLink: 'copia link',
copyImageLink: 'copia link immagine',
copyDeezerLink: 'copia link deezer',
paste: 'incolla',
listTabs: { listTabs: {
all: 'tutto', all: 'tutto',
top_result: 'miglior risultato', top_result: 'miglior risultato',
@ -24,6 +31,8 @@ const it = {
playlist: 'playlist', playlist: 'playlist',
compile: 'compilation', compile: 'compilation',
ep: 'ep', ep: 'ep',
more: 'Altri album',
featured: 'Compare in',
spotifyPlaylist: 'playlist spotify', spotifyPlaylist: 'playlist spotify',
releaseDate: 'data di uscita', releaseDate: 'data di uscita',
error: 'errore', error: 'errore',
@ -145,12 +154,15 @@ const it = {
searchbar: 'Cerca qualsiasi cosa (o incolla semplicemente un link)', searchbar: 'Cerca qualsiasi cosa (o incolla semplicemente un link)',
downloads: 'download', downloads: 'download',
toasts: { toasts: {
restoringQueue: 'Ripristinando la coda di download...',
queueRestored: 'Coda di download ripristinata!',
addedToQueue: '{0} aggiunto alla coda', addedToQueue: '{0} aggiunto alla coda',
addedMoreToQueue: '{0} oggetti aggiunti alla coda',
alreadyInQueue: '{0} è già nella coda!', alreadyInQueue: '{0} è già nella coda!',
finishDownload: '{0} ha finito di scaricarsi.', finishDownload: '{0} ha finito di scaricarsi.',
allDownloaded: 'Tutti i download completati!', allDownloaded: 'Tutti i download completati!',
refreshFavs: 'Preferiti ricaricati!', refreshFavs: 'Preferiti ricaricati!',
loggingIn: 'Effettuando il login', loggingIn: 'Effettuando il login...',
loggedIn: 'Login effettuato', loggedIn: 'Login effettuato',
alreadyLogged: 'Sei già loggato', alreadyLogged: 'Sei già loggato',
loginFailed: 'Impossibile loggarsi', loginFailed: 'Impossibile loggarsi',
@ -160,7 +172,8 @@ const it = {
startAddingArtist: 'Aggiungendo gli album di {0} alla coda', startAddingArtist: 'Aggiungendo gli album di {0} alla coda',
finishAddingArtist: 'Aggiunto gli album di {0} alla coda', finishAddingArtist: 'Aggiunto gli album di {0} alla coda',
startConvertingSpotifyPlaylist: 'Convertendo i brani da spotify a deezer', startConvertingSpotifyPlaylist: 'Convertendo i brani da spotify a deezer',
finishConvertingSpotifyPlaylist: 'Playlist di spotify convertita' finishConvertingSpotifyPlaylist: 'Playlist di spotify convertita',
loginNeededToDownload: 'Devi accedere prima di poter scaricare brani!'
}, },
settings: { settings: {
title: 'Impostazioni', title: 'Impostazioni',
@ -218,7 +231,9 @@ const it = {
title: 'Dovrei sovrascrivere i file già scaricati?', title: 'Dovrei sovrascrivere i file già scaricati?',
y: 'Si, sovrascrivi i file', y: 'Si, sovrascrivi i file',
n: 'No, non sovrascrivere i file', n: 'No, non sovrascrivere i file',
t: 'Sovrascrivi solo i tag' t: 'Sovrascrivi solo i tag',
b: 'No, mantieni entrambi i file e aggiungi un numero al duplicato',
e: "No, e non tener conto della estensione del file"
}, },
fallbackBitrate: 'Utilizza bitrate più bassi se il bitrate preferito non è disponibile', fallbackBitrate: 'Utilizza bitrate più bassi se il bitrate preferito non è disponibile',
fallbackSearch: 'Cerca il brano se il link originale non è disponibile', fallbackSearch: 'Cerca il brano se il link originale non è disponibile',
@ -243,7 +258,10 @@ const it = {
png: 'In png', png: 'In png',
both: 'Sia in jpeg che in png' both: 'Sia in jpeg che in png'
}, },
jpegImageQuality: 'Qualità immagine JPEG' jpegImageQuality: 'Qualità immagine JPEG',
embeddedArtworkPNG: 'Salva copertina incorporata come PNG',
embeddedPNGWarning: 'Le immagini PNG non sono usate ufficialmente da Deezer e potrebbero dare problemi',
imageSizeWarning: 'Dimensioni maggiori di x1200 non sono usate ufficialmente da Deezer, potresti incontrare problemi'
}, },
tags: { tags: {
head: 'Quali tag salvare', head: 'Quali tag salvare',

View File

@ -1,6 +1,6 @@
const ptBr = { const pt_br = {
globals: { globals: {
welcome: 'Bem vindo ao deemix', welcome: 'bem vindo ao deemix',
back: 'voltar', back: 'voltar',
loading: 'carregando', loading: 'carregando',
download: 'Baixar {0}', download: 'Baixar {0}',
@ -8,20 +8,20 @@
in: 'em {0}', in: 'em {0}',
download_hint: 'Baixar', download_hint: 'Baixar',
play_hint: 'Reproduzir', play_hint: 'Reproduzir',
toggle_download_tab_hint: 'Expandir/Recolher', toggle_download_tab_hint: 'Expandir/Diminuir',
clean_queue_hint: 'Limpar os terminados', clean_queue_hint: 'Limpar',
cancel_queue_hint: 'Cancelar todos', cancel_queue_hint: 'Cancelar Todos',
listTabs: { listTabs: {
empty: '', empty: '',
all: 'todos', all: 'todos',
top_result: 'Resultado principal', top_result: 'resultado principal',
album: 'álbum | álbuns', album: 'álbum | álbuns',
artist: 'artista | artistas', artist: 'artista | artistas',
single: 'single | singles', single: 'single | singles',
title: 'título | títulos', title: 'título | títulos',
track: 'faixa | faixas', track: 'faixa | faixas',
trackN: '0 faixas | {n} faixa | {n} faixas', trackN: '0 faixas | {n} faixa | {n} faixas',
releaseN: '0 lançamentos | {n} lançamento | {n} lançamentos', releaseN: '0 lançamento | {n} lançamento | {n} lançamentos',
playlist: 'playlist | playlists', playlist: 'playlist | playlists',
compile: 'compilação | compilações', compile: 'compilação | compilações',
ep: 'ep | eps', ep: 'ep | eps',
@ -39,253 +39,252 @@
license: 'Licença' license: 'Licença'
}, },
subtitles: { subtitles: {
bugReports: 'Tem algo não funcionando no deemix? Informe-nos!', bugReports: "Há algo não funcionando no deemix? Nos diga!",
contributing: 'Quer contribuir com este projeto? Há várias formas!', contributing: 'Você quer contribuir para este projeto? Você pode fazer isso de diferentes maneiras!',
donations: 'Quer contribuir monetariamente? Você pode fazer uma doação!' donations: 'Você quer contribuir monetariamente? Você pode fazer uma doação!'
}, },
usesLibrary: usesLibrary: 'Esse app usa a biblioteca do <strong>deemix</strong>, no qual você pode usar para criar sua própria UI para o deemix',
'Este programa usa a biblioteca <strong>deemix</strong>, no qual você pode usar para construir uma UI para o seu deemix.', thanks: `Agradecimentos para <strong>rtonno</strong>, <strong>uhwot</strong> e <strong>lollilol</strong> por ajudar neste projeto, e para <strong>BasCurtiz</strong> e <strong>scarvimane</strong> por fazerem o ícone`,
thanks: `Obrigado <strong>rtonno</strong>, <strong>uhwot</strong> e <strong>lollilol</strong> por me ajudarem com este projeto e <strong>BasCurtiz</strong> e <strong>scarvimane</strong> por fazerem o ícone.`, upToDate: `Para mais novidades siga o <a href="https://t.me/RemixDevNews" target="_blank">news channel</a> no Telegram.`,
upToDate: `Seja avisado quando houver novas atualizações, siga o <a href="https://t.me/RemixDevNews" target="_blank">nosso canal de notícias</a> no Telegram.`, officialWebsite: 'Site Oficial',
officialWebsite: 'Website Oficial',
officialRepo: 'Repositório da Biblioteca Oficial', officialRepo: 'Repositório da Biblioteca Oficial',
officialWebuiRepo: 'Repositório da WebUI Oficial', officialWebuiRepo: 'Repositório da WebUI Oficial',
officialSubreddit: 'Subreddit Oficial', officialSubreddit: 'Subreddit Oficial',
newsChannel: 'Canal de Notícia', newsChannel: 'Canal de Notícias',
questions: `Caso houver dúvidas ou problemas com o programa, procure uma solução no <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a>. Caso não encontre nada, você pode fazer um post com a sua dúvida no subreddit.`, questions: `Se você tiver dúvidas ou problemas com o app, procure uma solução em <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a> primeiro. Caso você não encontre, você pode fazer um post explicando seu problema no subreddit. `,
beforeReporting: `Antes de reportar um bug tenha certeza de que o seu deemix esteja atualizado e que o seu relato seja realmente um bug e não um problema no seu lado de usuário.`, beforeReporting: `Antes de reportar um bug, tenha certeza que você está rodando a versão mais recente do app, e o que você quer reportar seja realmente um bug e não algo que esteja acontecendo especialmente com você.`,
beSure: `Certifique-se de que o bug ocorra em outras máquinas e <strong>NÃO</strong> relate-o caso ele já tenha sido relatado.`, beSure: `Certifique-se que o bug é reproduzivel em outras máquinas e também <strong>NÃO</strong> reporte um bug se ele já foi reportado.`,
duplicateReports: 'Relatos duplicados de bug serão fechados, então fique de olho.', duplicateReports: 'Reportes de bugs duplicados serão fechados, então fique atento a isso.',
dontOpenIssues: `<strong>NÃO</strong> abra uma issue para fazer questões, o subreddit é para isso.`, dontOpenIssues: `<strong>NÃO</strong> abra tópicos para fazer perguntas, há o subreddit para isso.`,
newUI: `Caso seja fluente em python, você pode tentar fazer uma nova UI para o app usando a biblioteca base, ou consertar os bugs da biblioteca com uma pull request na <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repo do projeto</a>.`, newUI: `Se você é fluente em Phython, você pode tentar fazer uma nova UI para o app usando a biblioteca base, ou consertar bugs da biblioteca com um pull request em <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repo</a>.`,
acceptFeatures: `Eu aceito recursos também, mas nada muito complexo e que possa ser implementado diretamente no aplicativo e não na biblioteca.`, acceptFeatures: `Eu aceito funcionalidades extras também, mas nada de coisas complexas, desde que ela possa ser implementada no app, e não na biblioteca.`,
otherLanguages: `Caso seja fluente em outra linguagem de programação você pode tentar portar o deemix para ela!`, otherLanguages: `Se você for fluente em outra linguagem de programação, você pode tentar portar o deemix para outra linguagem!`,
understandingCode: `Precisa de ajuda para entender o código? Contate o RemixDev no Telegram ou Reddit.`, understandingCode: `Você precisa de ajuda para entender o código? Mande mensagem no RemixDex pelo Telegram ou pelo Reddit.`,
contributeWebUI: `Caso saiba Vue.js (JavaScript), HTML ou CSS você pode contribuir para a <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`, contributeWebUI: `Se você souber Vue.js (JavaScript), HTML ou CSS você pode contribuir para o <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`,
itsFree: `Mantenha em mente que <strong>este é um projeto gratuito</strong> e que <strong>você deve apoiar os artistas que ama</strong> antes de apoiar os desenvolvedores.`, itsFree: `Lembre-se que <strong>este projeto é livre</strong> e <strong>você deve dar suporte aos artistas que você ama</strong> antes de dar suporte aos desenvolvedores.`,
notObligated: `Não se sinta obrigado a doar, agradecemos da mesma forma!`, notObligated: `Não se sinta na obrigação de doar, eu agradeço de qualquer maneira!`,
lincensedUnder: `Este trabalho é licenciado sob a lincensedUnder: `Esse é um projeto licenciado através da
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank" <a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"
>GNU General Public License 3.0</a >GNU General Public License 3.0</a
>.` >.`
}, },
charts: { charts: {
title: 'Charts', title: 'Charts',
changeCountry: 'Trocar o país', changeCountry: 'Mudar País',
download: 'Baixe a chart' download: 'Download Chart'
}, },
errors: { errors: {
title: 'Erros para {0}', title: 'Erros para {0}',
ids: { ids: {
invalidURL: 'URL não reconhecida', invalidURL: 'URL inválida',
unsupportedURL: 'URL não suportada', unsupportedURL: 'URL não suportada ainda',
ISRCnotOnDeezer: 'ISRC da faixa não está no deezer', ISRCnotOnDeezer: 'Faixa ISRC não está disponível ainda no deezer',
notYourPrivatePlaylist: 'Você não pode baixar playlists privadas de outros usuários.', notYourPrivatePlaylist: "Você não pode baixar playlists privadas.",
spotifyDisabled: 'Recursos do Spotify não estão configurados corretamente.', spotifyDisabled: 'Os Recursos do Spotify não foram configurados corretamente.',
trackNotOnDeezer: 'Faixa não encontrada no deezer!', trackNotOnDeezer: 'Faixa não encontrada no deezer!',
albumNotOnDeezer: 'Álbum não encontrada no deezer!', albumNotOnDeezer: 'Album not found on deezer! Álbum não encontrado no deezer!',
notOnDeezer: 'Faixa não disponível no Deezer!', notOnDeezer: 'Faixa indisponível no deezer!',
notEncoded: 'Faixa ainda não encodada!', notEncoded: 'Faixa ainda não codificada!',
notEncodedNoAlternative: 'Faixa ainda não encodada e sem alternativas encontradas!', notEncodedNoAlternative: 'Faixa ainda não codificada e sem alternativas encontradas!',
wrongBitrate: 'Faixa não encontrada no bitrate desejado.', wrongBitrate: 'Faixa não encontrada no bitrate desejado.',
wrongBitrateNoAlternative: 'Faixa não encontrada no bitrate desejado e sem alternativas encontradas!', wrongBitrateNoAlternative: 'Faixa não encontrada no bitrate desejado e nenhuma outra alternativa encontrada!',
no360RA: 'Faixa não disponível no Reality Audio 360.', no360RA: 'Faixa não disponível na qualidade Reality Audio 360.',
notAvailable: 'Faixa não disponível nos servidores do deezer!', notAvailable: "Faixa não disponível nos servidores do deezer!",
notAvailableNoAlternative: 'Faixa não disponível nos servidores do deezer e sem alternativas encontradas!' notAvailableNoAlternative: "Faixa não disponível nos servidores do deezer e nenhuma outra alternativa encontrada!"
} }
}, },
favorites: { favorites: {
title: 'Favorites', title: 'Favoritos',
noPlaylists: 'Nenhuma playlists favorita encontrada', noPlaylists: 'Nenhuma Playlist encontrada',
noAlbums: 'Nenhum álbum favorito encontrado', noAlbums: 'Nenhum Álbum Favorito encontrado',
noArtists: 'Nenhum artista favorito encontrado', noArtists: 'Nenhum Artista Favorito encontrado',
noTracks: 'Nenhuma faixa favorita encontrada' noTracks: 'Nenhuma Faixa Favorita encontrada'
}, },
home: { home: {
needTologin: 'Você precisa logar na sua conta do Deezer antes de poder começar a baixar.', needTologin: 'Você precisa logar na sua conta do deezer antes de começar a baixar músicas.',
openSettings: 'Abrir configurações', openSettings: 'Abrir Configurações',
sections: { sections: {
popularPlaylists: 'Playlists populares', popularPlaylists: 'Playlists Populares',
popularAlbums: 'Álbuns mais ouvidos' popularAlbums: 'Álbuns mais ouvidos'
} }
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'Você pode usar esta seção para descobrir mais informações sobre o link que está tentando baixar.', info: 'Você pode usar essa seção para encontrar mais informações sobre o link que você quer baixar.',
useful: useful:
'Esta função é útil caso esteja tentando baixar algumas faixas que não estão disponíveis no seu país e você quer descobrir aonde estão disponíveis, por exemplo.', "Isso é útil se você está tentando baixar algumas faixas que não estão disponíveis no seu país, e quer saber onde elas estão disponíveis, por exemplo.",
linkNotSupported: 'Este link não é suportado ainda', linkNotSupported: 'Esse link não é suportado ainda',
linkNotSupportedYet: 'Aparentemente este link ainda não é suportado, tente analizar algum outro.', linkNotSupportedYet: 'Parece que esse link não é suportado ainda, tente analizar outro.',
table: { table: {
id: 'ID', id: 'ID',
isrc: 'ISRC', isrc: 'ISRC',
upc: 'UPC', upc: 'UPC',
duration: 'Duração', duration: 'Duração',
diskNumber: 'Número do disco', diskNumber: 'Número do Disco',
trackNumber: 'Número da faixa', trackNumber: 'Número da Faixa',
releaseDate: 'Data de lançamento', releaseDate: 'Data de Lançamento',
bpm: 'BPM', bpm: 'BPM',
label: 'Gravadora', label: 'Gravadora',
recordType: 'Tipo de gravação', recordType: 'Tipo de Gravação',
genres: 'Gêneros', genres: 'Gêneros',
tracklist: 'Lista de faixas' tracklist: 'Tracklist'
} }
}, },
search: { search: {
startSearching: 'Comece a procurar!', startSearching: 'Comece pesquisando!',
description: description:
'Você pode procurar uma faixa, um álbum inteiro, um artista, uma playlist... tudo! Você também pode colar um link do Deezer', 'Você pode pesquisar uma música, um álbum, um artista, uma playlist.... tudo! Você também pode colar um link do Deezer',
fans: '{0} fãs', fans: '{0} fãs',
noResults: 'Sem resultados', noResults: 'Sem resultados',
noResultsTrack: 'Nenhuma faixa encontrada', noResultsTrack: 'Nenhuma Faixa encontrada',
noResultsAlbum: 'Nenhum álbum encontrado', noResultsAlbum: 'Nenhum Álbum encontrado',
noResultsArtist: 'Nenhum artista encontrado', noResultsArtist: 'Nenhum Artista encontrado',
noResultsPlaylist: 'Nenhuma playlist encontrada' noResultsPlaylist: 'Nenhuma Playlist encontrada'
}, },
searchbar: 'Pesquise tudo o que quiser (ou simplesmente cole um link)', searchbar: 'Pesquise algo (ou apenas cole um link)',
downloads: 'downloads', downloads: 'downloads',
toasts: { toasts: {
addedToQueue: '{0} adicionado à lista de espera', addedToQueue: '{0} adicionado à fila',
alreadyInQueue: '{0} já está na lista de espera!', alreadyInQueue: '{0} já está na fila!',
finishDownload: '{0} terminou de baixar.', finishDownload: '{0} download terminado.',
allDownloaded: 'Todos os downloads terminaram!', allDownloaded: 'Todos os downloads foram feitos!',
refreshFavs: 'Atualização completa!', refreshFavs: 'Atualização completa!',
loggingIn: 'Entrando na conta', loggingIn: 'Logando',
loggedIn: 'Conta logada', loggedIn: 'Logado',
alreadyLogged: 'Já está na conta', alreadyLogged: 'Você já está logado',
loginFailed: 'Não pode entrar na conta', loginFailed: "Não foi possivel entrar",
loggedOut: 'Saindo da conta', loggedOut: 'Desconectando',
cancellingCurrentItem: 'Cancelando item atual.', cancellingCurrentItem: 'Cancelando item atual.',
currentItemCancelled: 'Cancelado item atual.', currentItemCancelled: 'Item atual cancelado.',
startAddingArtist: 'Adicionando {0} álbuns à lista de espera', startAddingArtist: 'Adicionando {0} álbuns à fila',
finishAddingArtist: '{0} álbuns adicionados à lista de espera', finishAddingArtist: '{0} álbuns adicionados a fila',
startConvertingSpotifyPlaylist: 'Convertendo faixas do Spotify para faixas do Deezer', startConvertingSpotifyPlaylist: 'Convertendo faixas do spotify para faixas do deezer',
finishConvertingSpotifyPlaylist: 'Playlist do Spotify convertida' finishConvertingSpotifyPlaylist: 'Playlists do Spotify convertidas'
}, },
settings: { settings: {
title: 'Configurações', title: 'Configurações',
languages: 'Linguagens', languages: 'Idiomas',
login: { login: {
title: 'Login', title: 'Login',
loggedIn: 'Você está logado como {username}', loggedIn: 'Você está logado como {username}',
arl: { arl: {
question: 'Como eu pego a minha ARL?', question: 'Como eu consigo o meu ARL?',
update: 'Atualizar a ARL' update: 'Atualizar ARL'
}, },
logout: 'Sair' logout: 'Sair'
}, },
appearance: { appearance: {
title: 'Aparência', title: 'Aparência',
slimDownloadTab: 'Guia de download slim' slimDownloadTab: 'Aba de download slim'
}, },
downloadPath: { downloadPath: {
title: 'Diretório de download' title: 'Diretório de Downloads'
}, },
templates: { templates: {
title: 'Templates', title: 'Templates',
tracknameTemplate: 'Template do nome da faixa avulsa', tracknameTemplate: 'Template do nome da faixa',
albumTracknameTemplate: 'Template do nome da faixa no álbum', albumTracknameTemplate: 'Template da faixa do álbum',
playlistTracknameTemplate: 'Template do nome da faixa na playlist' playlistTracknameTemplate: 'Template da faixa da playlist'
}, },
folders: { folders: {
title: 'Pastas', title: 'Pastas',
createPlaylistFolder: 'Criar pasta para playlists', createPlaylistFolder: 'Criar pasta para playlists',
playlistNameTemplate: 'Template do nome da pasta da playlist', playlistNameTemplate: 'Template da pasta de playlist',
createArtistFolder: 'Criar pasta para artistas', createArtistFolder: 'Criar pasta para os artistas',
artistNameTemplate: 'Template do nome da pasta do artista', artistNameTemplate: 'Template da pasta de artistas',
createAlbumFolder: 'Criar pasta para álbuns', createAlbumFolder: 'Criar pasta para álbuns',
albumNameTemplate: 'Template do nome da pasta do álbum', albumNameTemplate: 'Template da pasta de álbuns',
createCDFolder: 'Criar pasta para discos', createCDFolder: 'Criar pasta para CDs',
createStructurePlaylist: 'Criar estrutura de pasta para playlists', createStructurePlaylist: 'Criar estrutura de pastas para playlists',
createSingleFolder: 'Criar estrutura de pasta para singles' createSingleFolder: 'Criar estrutura de pastas para singles'
}, },
trackTitles: { trackTitles: {
title: 'Títulos das faixas', title: 'Título das faixas',
padTracks: 'Pad das faixas', padTracks: 'Faixas com pad',
paddingSize: 'Substituir tamanho do padding', paddingSize: 'Sobrescrever tamanho do padding',
illegalCharacterReplacer: 'Substituto de caracter ilegal' illegalCharacterReplacer: 'Substituir caracteres inválidos'
}, },
downloads: { downloads: {
title: 'Downloads', title: 'Downloads',
queueConcurrency: 'Downloads simultâneos', queueConcurrency: 'Downloads Simultâneos',
maxBitrate: { maxBitrate: {
title: 'Bitrate preferido', title: 'Escolher Taxa de Bits',
9: 'FLAC 1411kbps', 9: 'FLAC 1411kbps',
3: 'MP3 320kbps', 3: 'MP3 320kbps',
1: 'MP3 128kbps' 1: 'MP3 128kbps'
}, },
overwriteFile: { overwriteFile: {
title: 'Posso substituir os arquivos?', title: 'Sobrescrever arquivos?',
y: 'Sim, substitua os arquivos', y: 'Sim, sobrescrever arquivos',
n: 'Não, não substitua os arquivos', n: "Não, não sobrescrever arquivos",
t: 'Substitua apenas as tags' t: 'Sobrescrever apenas as tags'
}, },
fallbackBitrate: 'Bitrate reserva', fallbackBitrate: 'Taxa de bits reserva',
fallbackSearch: 'Pesquisa reserva', fallbackSearch: 'Procurar reserva',
logErrors: 'Criar log para erros', logErrors: 'Criar arquivos de log para erros',
logSearched: 'Criar log para faixas pesquisadas', logSearched: 'Criar arquivos de log para faixas pesquisadas',
createM3U8File: 'Criar arquivo de playlist', createM3U8File: 'Criar arquivo de playlist',
syncedLyrics: 'Criar arquivos .lyr (Letras sincronizadas)', syncedLyrics: 'Criar arquivos .lyr (Letras)',
playlistFilenameTemplate: 'Template do nome da playlist', playlistFilenameTemplate: 'Template do nome do arquivo da playlist',
saveDownloadQueue: 'Salvar lista de espera do download ao fechar o programa' saveDownloadQueue: 'Salvar a fila de downloads quando fechar o app'
}, },
covers: { covers: {
title: 'Capa dos álbuns', title: 'Capa dos álbuns',
saveArtwork: 'Salvar as capas', saveArtwork: 'Salvar capas',
coverImageTemplate: 'Template do nome da capa', coverImageTemplate: 'Template do nome da capa',
saveArtworkArtist: 'Salvar imagem do artista', saveArtworkArtist: 'Salvar imagem do artista',
artistImageTemplate: 'Template da imagem do artista', artistImageTemplate: 'Template da imagem do artista',
localArtworkSize: 'Tamanho da artwork local', localArtworkSize: 'Tamanho da capa local',
embeddedArtworkSize: 'Tamanho da artwork embutida', embeddedArtworkSize: 'Tamanho da capa embutida',
localArtworkFormat: { localArtworkFormat: {
title: 'Qual formato você quer que a artwork local seja?', title: 'Qual o formato da imagem que você quer para a capa local?',
jpg: 'Uma imagem jpeg', jpg: '.jpeg',
png: 'Uma imagem png', png: '.png',
both: 'Ambos um jpeg e um png' both: 'Ambas, .jpeg e .png'
}, },
jpegImageQuality: 'Qualidade do JPEG' jpegImageQuality: 'Qualidade da imagem JPEG'
}, },
tags: { tags: {
head: 'Quais tags salvar', head: 'Quais tags salvar',
title: 'Título', title: 'Título',
artist: 'Artista', artist: 'Artista',
album: 'Álbuns', album: 'Álbum',
cover: 'Capa', cover: 'Capa',
trackNumber: 'Número da faixa', trackNumber: 'Número da Faixa',
trackTotal: 'Total de faixas', trackTotal: 'Total de Faixas',
discNumber: 'Número de discos', discNumber: 'Número de Discos',
discTotal: 'Total de discos', discTotal: 'Total de Discos',
albumArtist: 'Artista do álbum', albumArtist: 'Artista do Álbum',
genre: 'Gênero', genre: 'Gênero',
year: 'Ano', year: 'Ano',
date: 'Data', date: 'Data',
explicit: 'Letras explícitas', explicit: 'Letras Explícitas',
isrc: 'ISRC', isrc: 'ISRC',
length: 'Tamanho da faixa', length: 'Tamanho da Faixa',
barcode: 'Barcode do álbum (UPC)', barcode: 'Código de Barras do álbum (UPC)',
bpm: 'BPM', bpm: 'BPM',
replayGain: 'Replay Gain', replayGain: 'Replay Gain',
label: 'Gravadora do álbum', label: 'Gravadora',
lyrics: 'Letras desincronizadas', lyrics: 'Letras Dessincronizadas',
copyright: 'Copyright', copyright: 'Copyright',
composer: 'Compositor', composer: 'Compositor',
involvedPeople: 'Pessoas involvidas' involvedPeople: 'Pessoas Envolvidas'
}, },
other: { other: {
title: 'Outros', title: 'Outros',
savePlaylistAsCompilation: 'Savar playlists como uma compilação', savePlaylistAsCompilation: 'Salvar playlists como uma compilação',
useNullSeparator: 'Usar separador nulo', useNullSeparator: 'Usar separador nulo',
saveID3v1: 'Salvar ID3v1', saveID3v1: 'Salvar ID3v1',
multiArtistSeparator: { multiArtistSeparator: {
title: 'Como gostaria de separar seus artistas?', title: 'Como você gostaria de separar os artistas?',
nothing: 'Salvar apenas o artista principal', nothing: 'Salvar apenas o artista principal',
default: 'Usando especificação padrão', default: 'Usar a especificação padrão',
andFeat: 'Usando & e feat.', andFeat: 'Usar & e feat.',
using: 'Usando "{0}"' using: 'Usar "{0}"'
}, },
singleAlbumArtist: 'Salvar apenas o artista principal do álbum', singleAlbumArtist: 'Salvar apenas o artista principal',
albumVariousArtists: 'Manter "Various Artists" em Artistas do Álbum', albumVariousArtists: 'Manter "Various Artists" nos Artistas do Álbum',
removeAlbumVersion: 'Remover "Album Version" do título de faixas', removeAlbumVersion: 'Remover "Album Version" do título da faixa',
removeDuplicateArtists: 'Remover combinações de artistas', removeDuplicateArtists: 'Remover combinação de artistas',
dateFormat: { dateFormat: {
title: 'Formato da data para arquivos FLAC', title: 'Formato da data para arquivos FLAC',
year: 'AAAA', year: 'AAAA',
@ -293,43 +292,43 @@
day: 'DD' day: 'DD'
}, },
featuredToTitle: { featuredToTitle: {
title: 'O que eu deveria fazer com os artistas feat.?', title: 'O que devo fazer com artistas participantes?',
0: 'Nada', 0: 'Nada',
1: 'Remova-os do título da faixa', 1: 'Remova do título da faixa',
3: 'Remova-os do título da faixa e do álbum', 3: 'Remova do título da faixa e do álbum',
2: 'Mova-os para o título da faixa' 2: 'Mover para o título da faixa'
}, },
titleCasing: 'Formatação do título', titleCasing: 'Formatação do título',
artistCasing: 'Formatação do artista', artistCasing: 'Formatação do artista',
casing: { casing: {
nothing: 'Manter intocado', nothing: 'Manter inalterado',
lower: 'minúsculo', lower: 'minúsculo',
upper: 'MAIÚSCULO', upper: 'MAIÚSCULO',
start: 'No Começo De Cada Palavra', start: 'Começo De Cada Palavra',
sentence: 'Como uma frase' sentence: 'Como uma frase'
}, },
previewVolume: 'Volume da prévia', previewVolume: 'Prévia do Volume',
executeCommand: { executeCommand: {
title: 'Comando para executar depois do download', title: 'Comando para executar depois de baixar',
description: 'Deixe em branco para não executar nada' description: 'Deixe em branco para nenhuma ação'
} }
}, },
spotify: { spotify: {
title: 'Destaques do Spotify', title: 'Recursos do Spotify',
clientID: 'Spotify clientID', clientID: 'Spotify clientID',
clientSecret: 'Spotify Client Secret', clientSecret: 'Spotify Client Secret',
username: 'Nome de usuário do Spotify' username: 'usuário do Spotify'
}, },
reset: 'Resetar para Padrão', reset: 'Restaurar para o padrão',
save: 'Save', save: 'Salvar',
toasts: { toasts: {
init: 'Configurações carregadas!', init: 'Configurações carregadas!',
update: 'Configurações atualizadas!', update: 'Configurações atualizadas!',
ARLcopied: 'ARL copiado para o clipboard' ARLcopied: 'ARL copiada para a área de transferência'
} }
}, },
sidebar: { sidebar: {
home: 'home', home: 'início',
search: 'pesquisa', search: 'pesquisa',
charts: 'charts', charts: 'charts',
favorites: 'favoritos', favorites: 'favoritos',
@ -342,4 +341,4 @@
} }
} }
export default ptBr export default pt_br

View File

@ -1,345 +1,342 @@
const pt = { const pt = {
globals: { globals: {
welcome: 'Bem-vindo ao deemix', welcome: 'Bem-vindo ao deemix',
back: 'voltar', back: 'voltar',
loading: 'A carregar', loading: 'A carregar',
download: 'Transferir {0}', download: 'Transferir {0}',
by: 'por {0}', by: 'por {0}',
in: 'em {0}', in: 'em {0}',
download_hint: 'Descarregar', download_hint: 'Transferir',
play_hint: 'Tocar', play_hint: 'Tocar',
toggle_download_tab_hint: 'Expandir/Recolher', toggle_download_tab_hint: 'Expandir/Recolher',
clean_queue_hint: 'Limpar Finalizados', clean_queue_hint: 'Limpar Finalizados',
cancel_queue_hint: 'Cancelar Tudo', cancel_queue_hint: 'Cancelar Tudo',
listTabs: { listTabs: {
empty: '', empty: '',
all: 'Tudo', all: 'Tudo',
top_result: 'melhor resultado', top_result: 'melhor resultado',
album: 'álbum | álbums', album: 'álbum | álbums',
artist: 'artista | artistas', artist: 'artista | artistas',
single: 'single | singles', single: 'single | singles',
title: 'título | títulos', title: 'título | títulos',
track: 'faixa | faixas', track: 'faixa | faixas',
trackN: '0 faixas | {n} faixa | {n} faixas', trackN: '0 faixas | {n} faixa | {n} faixas',
releaseN: '0 lançamentos | {n} lançamento | {n} lançamento', releaseN: '0 lançamentos | {n} lançamento | {n} lançamento',
playlist: 'lista de reprodução | listas de reprodução', playlist: 'lista de reprodução | listas de reprodução',
compile: 'compilação | compilações', compile: 'compilação | compilações',
ep: 'ep | eps', ep: 'ep | eps',
spotifyPlaylist: 'lista de reprodução spotify | listas de reprodução spotify', spotifyPlaylist: 'lista de reprodução spotify | listas de reprodução spotify',
releaseDate: 'data de lançamento', releaseDate: 'data de lançamento',
error: 'erro' error: 'erro'
} }
}, },
about: { about: {
titles: { titles: {
usefulLinks: 'Links Úteis', usefulLinks: 'Links Úteis',
bugReports: 'Relatório de erros', bugReports: 'Relatório de erros',
contributing: 'Contribuir', contributing: 'Contribuir',
donations: 'Doações', donations: 'Doações',
license: 'Licenças' license: 'Licenças'
}, },
subtitles: { subtitles: {
bugReports: 'Existe alguma coisa que não funciona no deemix? Informa-nos!', bugReports: 'Existe alguma coisa que não funciona no deemix? Informa-nos!',
contributing: 'Queres contribuir para o projecto? Podes fazê-lo de diferentes formas!', contributing: 'Queres contribuir para o projecto? Podes fazê-lo de diferentes formas!',
donations: 'Desejas contribuir monetariamente? Faz uma doação!' donations: 'Desejas contribuir monetariamente? Faz uma doação!'
}, },
usesLibrary: usesLibrary: 'Esta aplicação usa a biblioteca <strong>deemix</strong>, que poderás usar para desenvolver o teu proprio UI para o deemix.',
'Esta aplicação usa a biblioteca <strong>deemix</strong>, que poderás usar para desenvolver o teu proprio UI para o deemix.', thanks: `Agradeço a <strong>rtonno</strong>, <strong>uhwot</strong> and <strong>lollilol</strong> por me ajudarem neste projeto e a <strong>BasCurtiz</strong> and <strong>scarvimane</strong> por elaborarem o ícone.`,
thanks: `Agradeço a <strong>rtonno</strong>, <strong>uhwot</strong> and <strong>lollilol</strong> por me ajudarem neste projeto e a <strong>BasCurtiz</strong> and <strong>scarvimane</strong> por elaborarem o ícone.`, upToDate: `Mantem-te atualizado seguindo o <a href="https://t.me/RemixDevNews" target="_blank">canal de notícias</a> no Telegram.`,
upToDate: `Mantem-te atualizado seguindo o <a href="https://t.me/RemixDevNews" target="_blank">canal de notícias</a> no Telegram.`, officialWebsite: 'Site Oficial',
officialWebsite: 'Site Oficial', officialRepo: 'Repositório Oficial da Biblioteca',
officialRepo: 'Repositório Oficial da Biblioteca', officialWebuiRepo: 'Repositório Oficial WebUI',
officialWebuiRepo: 'Repositório Oficial WebUI', officialSubreddit: 'Subreddit Oficial',
officialSubreddit: 'Subreddit Oficial', newsChannel: 'Canal de Notícias',
newsChannel: 'Canal de Notícias', questions: `Caso tenhas alguma duvida ou problema com a app, primeiro procura por uma solução no <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a>. Caso não encontres nada podes criar um post com a tua questão no subreddit.`,
questions: `Caso tenhas alguma duvida ou problema com a app, primeiro procura por uma solução no <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a>. Caso não encontres nada podes criar um post com a tua questão no subreddit.`, beforeReporting: `Antes de reportares um bug certifica-te que estás a correr a versão mais recente e que o que queres reportar é mesmo um bug e não algo que apenas não funciona do teu lado.`,
beforeReporting: `Antes de reportares um bug certifica-te que estás a correr a versão mais recente e que o que queres reportar é mesmo um bug e não algo que apenas não funciona do teu lado.`, beSure: `Certifica-te que o erro é reprodutivel noutros dispositivos e <strong>NÃO</strong> reportes um bug que já tenha sido reportado.`,
beSure: `Certifica-te que o erro é reprodutivel noutros dispositivos e <strong>NÃO</strong> reportes um bug que já tenha sido reportado.`, duplicateReports: 'Bug reports duplicados serão fechados, mantém-te atento a isso.',
duplicateReports: 'Bug reports duplicados serão fechados, mantém-te atento a isso.', dontOpenIssues: `<strong>NÃO</strong> abras issues para colocar questões, existe um subreddit para isso.`,
dontOpenIssues: `<strong>NÃO</strong> abras issues para colocar questões, existe um subreddit para isso.`, newUI: `Caso sejas fluente em python podes tentar criar um novo UI para a aplicação recorrendo à biblioteca base , ou corrigir erros na biblioteca com um pull request no <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repositório</a>.`,
newUI: `Caso sejas fluente em python podes tentar criar um novo UI para a aplicação recorrendo à biblioteca base , ou corrigir erros na biblioteca com um pull request no <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repositório</a>.`, acceptFeatures: `Também aceito funcionalidades não complexas caso possam ser implementadas directamente na app e não na biblioteca.`,
acceptFeatures: `Também aceito funcionalidades não complexas caso possam ser implementadas directamente na app e não na biblioteca.`, otherLanguages: `Caso sejas fluente noutra linguagem de programação podes tentar migrar o deemix para outra linguagem de programação!`,
otherLanguages: `Caso sejas fluente noutra linguagem de programação podes tentar migrar o deemix para outra linguagem de programação!`, understandingCode: `Precisas de ajuda a entender o código? Acede a RemixDev no Telegram ou no Reddit.`,
understandingCode: `Precisas de ajuda a entender o código? Acede a RemixDev no Telegram ou no Reddit.`, contributeWebUI: `Caso saibas Vue.js (JavaScript), HTML ou CSS podes contribuir para o <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`,
contributeWebUI: `Caso saibas Vue.js (JavaScript), HTML ou CSS podes contribuir para o <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`, itsFree: `Deves ter em conta que <strong>que este projecto é gratuito</strong> e <strong>deverás apoiar os artistas que aprecias</strong> antes de apoiares os programadores.`,
itsFree: `Deves ter em conta que <strong>que este projecto é gratuito</strong> e <strong>deverás apoiar os artistas que aprecias</strong> antes de apoiares os programadores.`, notObligated: `Não te sintas obrigado a doar, agradeço-te na mesma!`,
notObligated: `Não te sintas obrigado a doar, agradeço-te na mesma!`, lincensedUnder: `Este trabalho esta licenciado sobre a
lincensedUnder: `This work is licensed under a
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank" <a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"
>GNU General Public License 3.0</a >GNU Licença publica geral 3.0</a
>.` >.`
}, },
charts: { charts: {
title: 'Tabelas', title: 'Tabelas',
changeCountry: 'Alterar país', changeCountry: 'Alterar país',
download: 'Descarregar tabela' download: 'Transferir tabela'
}, },
errors: { errors: {
title: 'Erros para {0}', title: 'Erros para {0}',
ids: { ids: {
invalidURL: 'URL não reconhecido', invalidURL: 'URL não reconhecido',
unsupportedURL: 'URL ainda não suportado', unsupportedURL: 'URL ainda não suportado',
ISRCnotOnDeezer: 'Track ISRC não disponível no deezer', ISRCnotOnDeezer: 'Faixa ISRC não disponível no deezer',
notYourPrivatePlaylist: "You can't download others private playlists.", notYourPrivatePlaylist: "Nao podes baixar listas de reprodução privadas de outros.",
spotifyDisabled: 'Funcionalidades do Spotify não estão definidas corretamente.', spotifyDisabled: 'Funcionalidades do Spotify não estão definidas corretamente.',
trackNotOnDeezer: 'Faixa não encontrada no deezer!', trackNotOnDeezer: 'Faixa não encontrada no deezer!',
albumNotOnDeezer: 'Álbum não encontrado no deezer!', albumNotOnDeezer: 'Álbum não encontrado no deezer!',
notOnDeezer: 'Faixa não encontrada no Deezer!', notOnDeezer: 'Faixa não encontrada no Deezer!',
notEncoded: 'Faixa ainda não codificada!', notEncoded: 'Faixa ainda não codificada!',
notEncodedNoAlternative: 'Faixa ainda não codificada e não foi encontrada alternativa!', notEncodedNoAlternative: 'Faixa ainda não codificada e não foi encontrada alternativa!',
wrongBitrate: 'Faixa não encontrada no bitrate desejado.', wrongBitrate: 'Faixa não encontrada no bitrate desejado.',
wrongBitrateNoAlternative: 'Faixa não encontrada no bitrate desejado e não foi encontrada alternativa!', wrongBitrateNoAlternative: 'Faixa não encontrada no bitrate desejado e não foi encontrada alternativa!',
no360RA: 'Faixa não disponível em Reality Audio 360.', no360RA: 'Faixa não disponível em Reality Audio 360.',
notAvailable: 'Faixa não disponível nos servidores do deezer!', notAvailable: 'Faixa não disponível nos servidores do deezer!',
notAvailableNoAlternative: 'Faixa não disponível nos servidores do deezer e não foi encontrada alternativa!' notAvailableNoAlternative: 'Faixa não disponível nos servidores do deezer e não foi encontrada alternativa!'
} }
}, },
favorites: { favorites: {
title: 'Favoritos', title: 'Favoritos',
noPlaylists: 'Listas de reprodução não encontradas', noPlaylists: 'Listas de reprodução não encontradas',
noAlbums: 'Álbuns favoritos não encontrados', noAlbums: 'Álbuns favoritos não encontrados',
noArtists: 'Artistas favoritos não encontrados', noArtists: 'Artistas favoritos não encontrados',
noTracks: 'Faixas favoritas não encontradas' noTracks: 'Faixas favoritas não encontradas'
}, },
home: { home: {
needTologin: 'Antes de iniciar transferências é necessário efectuar autenticação na conta Deezer.', needTologin: 'Antes de iniciar transferências é necessário efectuar autenticação na conta Deezer.',
openSettings: 'Abrir Definições', openSettings: 'Abrir Definições',
sections: { sections: {
popularPlaylists: 'Listas de reprodução populares', popularPlaylists: 'Listas de reprodução populares',
popularAlbums: 'Álbuns mais ouvidos' popularAlbums: 'Álbuns mais ouvidos'
} }
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'Podes usar esta secção para obteres mais informação sobre o link que estás a tentar transferir.', info: 'Podes usar esta secção para obteres mais informação sobre o link que estás a tentar transferir.',
useful: useful: 'Isto é útil caso estejas a tentar transferir faixas que não estão disponíveis no teu país e queres saber onde estão disponíveis, por exemplo.',
'Isto é útil caso estejas a tentar transferir faixas que não estão disponíveis no teu país e queres saber onde estão disponíveis, por exemplo.', linkNotSupported: 'Este link ainda não é suportado',
linkNotSupported: 'Este link ainda não é suportado', linkNotSupportedYet: 'Parece que este link ainda não é suportado, tenta analisar outro.',
linkNotSupportedYet: 'Parece que este link ainda não é suportado, tenta analisar outro.', table: {
table: { id: 'ID',
id: 'ID', isrc: 'ISRC',
isrc: 'ISRC', upc: 'UPC',
upc: 'UPC', duration: 'Duração',
duration: 'Duração', diskNumber: 'Número do disco',
diskNumber: 'Número do disco', trackNumber: 'Número da faixa',
trackNumber: 'Número da faixa', releaseDate: 'Data de lançamento',
releaseDate: 'Data de lançamento', bpm: 'BPM',
bpm: 'BPM', label: 'Editora',
label: 'Editora', recordType: 'Tipo de Disco',
recordType: 'Record Type', genres: 'Géneros',
genres: 'Géneros', tracklist: 'Lista de faixas'
tracklist: 'Lista de faixas' }
} },
}, search: {
search: { startSearching: 'Começa a pesquisar!',
startSearching: 'Começa a pesquisar!', description: 'Podes perquisar uma música, um álbum inteiro, um artista, uma lista de reprodução... tudo! Também podes colar um link do Deezer',
description: fans: '{0} fãs',
'Podes perquisar uma música, um álbum inteiro, um artista, uma lista de reprodução... tudo! Também podes colar um link do Deezer', noResults: 'Sem resultados',
fans: '{0} fãs', noResultsTrack: 'Faixa não encontrada',
noResults: 'Sem resultados', noResultsAlbum: 'Álbum não encontrado',
noResultsTrack: 'Faixa não encontrada', noResultsArtist: 'Artista não encontrado',
noResultsAlbum: 'Álbum não encontrado', noResultsPlaylist: 'Lista de reprodução não encontrada'
noResultsArtist: 'Artista não encontrado', },
noResultsPlaylist: 'Lista de reprodução não encontrada' searchbar: 'Pesquisa o que quiseres (ou cola um link)',
}, downloads: 'transferências',
searchbar: 'Pesquisa o que quiseres (ou cola um link)', toasts: {
downloads: 'transferências', addedToQueue: '{0} adicionados à fila',
toasts: { alreadyInQueue: '{0} já está na fila!',
addedToQueue: '{0} adicionados à fila', finishDownload: '{0} foi transferido.',
alreadyInQueue: '{0} já está na fila!', allDownloaded: 'Todas as transferências terminadas!',
finishDownload: '{0} foi transferido.', refreshFavs: 'Actualizar terminados!',
allDownloaded: 'Todas as transferências terminadas!', loggingIn: 'A autenticar',
refreshFavs: 'Actualizar terminados!', loggedIn: 'Autenticado',
loggingIn: 'A autenticar', alreadyLogged: 'Já estás autenticado',
loggedIn: 'Autenticado', loginFailed: "Nao foi possivel iniciar sessão",
alreadyLogged: 'Já estás autenticado', loggedOut: 'Desconectado',
loginFailed: "Couldn't log in", cancellingCurrentItem: 'A cancelar item actual.',
loggedOut: 'Logged out', currentItemCancelled: 'Item actual cancelado.',
cancellingCurrentItem: 'A cancelar item actual.', startAddingArtist: 'A adicionar {0} álbuns à fila',
currentItemCancelled: 'Item actual cancelado.', finishAddingArtist: 'Adicionados {0} álbuns à fila',
startAddingArtist: 'A adicionar {0} álbuns à fila', startConvertingSpotifyPlaylist: 'A converter faixas do spotify em faixas do deezer',
finishAddingArtist: 'Adicionados {0} álbuns à fila', finishConvertingSpotifyPlaylist: 'Lista de reprodução do Spotify convertida.'
startConvertingSpotifyPlaylist: 'A converter faixas do spotify em faixas do deezer', },
finishConvertingSpotifyPlaylist: 'Lista de reprodução do Spotify convertida.' settings: {
}, title: 'Definições',
settings: { languages: 'Idioma',
title: 'Definições', login: {
languages: 'Idioma', title: 'Inicio de Sessão',
login: { loggedIn: 'Estás autenticado como {username}',
title: 'Login', arl: {
loggedIn: 'Estás autenticado como {username}', question: 'Como obter o meu ARL?',
arl: { update: 'Actualizar ARL'
question: 'Como obter o meu ARL?', },
update: 'Atualizar ARL' logout: 'Sair'
}, },
logout: 'Sair' appearance: {
}, title: 'Aspecto',
appearance: { slimDownloadTab: 'Aba de transferências estreita'
title: 'Aspecto', },
slimDownloadTab: 'Aba de transferências estreita' downloadPath: {
}, title: 'Caminho das transferências'
downloadPath: { },
title: 'Caminho de transferências' templates: {
}, title: 'Formatos',
templates: { tracknameTemplate: 'Formato do nome de faixa',
title: 'Formatos', albumTracknameTemplate: 'Formato do nome de Álbum',
tracknameTemplate: 'Formato do nome de faixa', playlistTracknameTemplate: 'Formato do nome de lista de reprodução'
albumTracknameTemplate: 'Formato do nome de Álbum', },
playlistTracknameTemplate: 'Formato do nome de lista de reprodução' folders: {
}, title: 'Pastas',
folders: { createPlaylistFolder: 'Criar pasta para lista de reprodução',
title: 'Pastas', playlistNameTemplate: 'Formato da pasta de lista de reprodução',
createPlaylistFolder: 'Criar pasta para lista de reprodução', createArtistFolder: 'Criar pasta para artista',
playlistNameTemplate: 'Formato da pasta de lista de reprodução', artistNameTemplate: 'Formato da pasta de artista',
createArtistFolder: 'Criar pasta para artista', createAlbumFolder: 'Criar pasta para álbum',
artistNameTemplate: 'Formato da pasta de artista', albumNameTemplate: 'Formato da pasta de álbum',
createAlbumFolder: 'Criar pasta para álbum', createCDFolder: 'Criar pasta para CDs',
albumNameTemplate: 'Formato da pasta de álbum', createStructurePlaylist: 'Criar estrutura de pastas para listas reprodução',
createCDFolder: 'Criar pasta para CDs', createSingleFolder: 'Criar estrutura de pastas para singles'
createStructurePlaylist: 'Criar estrutura de pastas para listas reprodução', },
createSingleFolder: 'Criar estrutura de pastas para singles' trackTitles: {
}, title: 'Título',
trackTitles: { padTracks: 'Bloco de Faixas',
title: 'Título', paddingSize: 'Substituir tamanho do preenchimento',
padTracks: 'Pad tracks', illegalCharacterReplacer: 'Substituir caractere inválido'
paddingSize: 'Overwrite padding size', },
illegalCharacterReplacer: 'Substituir caractere inválidos' downloads: {
}, title: 'Transferências',
downloads: { queueConcurrency: 'Transferências concorrentes',
title: 'Transferências', maxBitrate: {
queueConcurrency: 'Transferências concorrentes', title: 'Bitrate preferencial',
maxBitrate: { 9: 'FLAC 1411kbps',
title: 'Bitrate preferencial', 3: 'MP3 320kbps',
9: 'FLAC 1411kbps', 1: 'MP3 128kbps'
3: 'MP3 320kbps', },
1: 'MP3 128kbps' overwriteFile: {
}, title: 'Ficheiros existentes. Substituir?',
overwriteFile: { y: 'Sim, substituir o ficheiro',
title: 'Ficheiros existentes. Substituir?', n: 'Não substituir o ficheiro',
y: 'Sim, substituir o ficheiro', t: 'Subescrever apenas as etiquetas'
n: 'Não substituir o ficheiro', },
t: 'Sobrescrever apenas as etiquetas' fallbackBitrate: 'Bitrate fallback',
}, fallbackSearch: 'Fallback de pesquisa',
fallbackBitrate: 'Bitrate fallback', logErrors: 'Criar histórico para erros',
fallbackSearch: 'Fallback de pesquisa', logSearched: 'Criar histórico para faixas pesquisadas',
logErrors: 'Criar logs para erros', createM3U8File: 'Criar ficheiro de lista de reprodução',
logSearched: 'Criar logs para faixas pesquisadas', syncedLyrics: 'Criar ficheiro .lyr (Letra Sincronizada)',
createM3U8File: 'Criar ficheiro de lista de reprodução', playlistFilenameTemplate: 'Formato do nome de ficheiro da lista de reprodução',
syncedLyrics: 'Criar ficheiro .lyr (Letras Sincronizadas)', saveDownloadQueue: 'Guardar fila de transferências ao fechar a aplicação'
playlistFilenameTemplate: 'Formato do nome de ficheiro playlists', },
saveDownloadQueue: 'Guardar fila de transferências ao fechar a aplicação' covers: {
}, title: 'Capas do Álbum',
covers: { saveArtwork: 'Guardar capas',
title: 'Capas do Álbum', coverImageTemplate: 'Modelo do nome da capa',
saveArtwork: 'Guardar capas', saveArtworkArtist: 'Salvar imagem do artista',
coverImageTemplate: 'Cover name template', artistImageTemplate: 'Modelo de imagem do artista',
saveArtworkArtist: 'Save artist image', localArtworkSize: 'Tamanho do trabalho artístico local',
artistImageTemplate: 'Artist image template', embeddedArtworkSize: 'Tamanho do trabalho artístico incorporado',
localArtworkSize: 'Local artwork size', localArtworkFormat: {
embeddedArtworkSize: 'Embedded artwork size', title: 'Em que formato desejas o trabalho artístico local?',
localArtworkFormat: { jpg: 'Em imagem jpeg',
title: 'What format do you want the local artwork to be?', png: 'Em imagem png',
jpg: 'A jpeg image', both: 'Em jpeg e em png'
png: 'A png image', },
both: 'Both a jpeg and a png' jpegImageQuality: 'Qualidade de imagem JPEG'
}, },
jpegImageQuality: 'Qualidade de imagem JPEG' tags: {
}, head: 'Etiquetas a guardar',
tags: { title: 'Título',
head: 'Etiquetas a guardar', artist: 'Artista',
title: 'Título', album: 'Álbum',
artist: 'Artista', cover: 'Capa',
album: 'Álbum', trackNumber: 'Número de faixa',
cover: 'Capa', trackTotal: 'Total de faixas',
trackNumber: 'Número de faixa', discNumber: 'Número do Disco',
trackTotal: 'Total de faixas', discTotal: 'Total de Discos',
discNumber: 'Número do Disco', albumArtist: 'Artista do Álbum',
discTotal: 'Total de Discos', genre: 'Género',
albumArtist: 'Artista do Álbum', year: 'Ano',
genre: 'Género', date: 'Data',
year: 'Ano', explicit: 'Letra Explícita',
date: 'Data', isrc: 'ISRC',
explicit: 'Letra Explícita', length: 'Duração da faixa',
isrc: 'ISRC', barcode: 'Código de barras do álbum (UPC)',
length: 'Duração da faixa', bpm: 'BPM',
barcode: 'Código de barras do álbum (UPC)', replayGain: 'ReplayGain',
bpm: 'BPM', label: 'Editora do álbum',
replayGain: 'Replay Gain', lyrics: 'Letra da música não sincronizada',
label: 'Editora do álbum', copyright: 'Direitos de Autor',
lyrics: 'Unsynchronized Lyrics', composer: 'Compositor',
copyright: 'Copyright', involvedPeople: 'Pessoas envolvidas'
composer: 'Compositor', },
involvedPeople: 'Pessoas envolvidas' other: {
}, title: 'Outros',
other: { savePlaylistAsCompilation: 'Guardar listas de reprodução como compilação',
title: 'Outros', useNullSeparator: 'Usar separador nulo',
savePlaylistAsCompilation: 'Save playlists as compilation', saveID3v1: 'Também guardar ID3v1',
useNullSeparator: 'Usar separador null', multiArtistSeparator: {
saveID3v1: 'Também guardar ID3v1', title: 'Como queres separarar os artistas?',
multiArtistSeparator: { nothing: 'Guardar apenas o artista principal',
title: 'Como queres separarar os artistas?', default: 'Usar especificação padrão',
nothing: 'Guardar apenas o artista principal', andFeat: 'Usar & e feat.',
default: 'Usar especificação padrão', using: 'Usar "{0}"'
andFeat: 'Usar & e feat.', },
using: 'Usar "{0}"' singleAlbumArtist: 'Guardar apenas o artista principal do álbum',
}, albumVariousArtists: 'Manter "Various Artists" nos Artistas do Álbum',
singleAlbumArtist: 'Guardar apenas o artista principal do álbum', removeAlbumVersion: 'Remover "Album Version" do título da faixa',
albumVariousArtists: 'Manter "Various Artists" nos Artistas do Álbum', removeDuplicateArtists: 'Remover combinação de artistas',
removeAlbumVersion: 'Remover "Album Version" do título da faixa', dateFormat: {
removeDuplicateArtists: 'Remover combinação de artistas', title: 'Formato de data nos ficheiros FLAC',
dateFormat: { year: 'AAAA',
title: 'Formtado de data nos ficheiros FLAC', month: 'MM',
year: 'AAAA', day: 'DD'
month: 'MM', },
day: 'DD' featuredToTitle: {
}, title: 'O que devo fazer com artistas convidados/participações?',
featuredToTitle: { 0: 'Nada',
title: 'What should I do with featured artists?', 1: 'Remover do título',
0: 'Nada', 3: 'Remover do título e do título do album',
1: 'Remover do título', 2: 'Movê-lo para o título'
3: 'Remover do título de do título do album', },
2: 'Movê-lo para o título' titleCasing: 'Caixa do Título',
}, artistCasing: 'Caixa do Artista',
titleCasing: 'Title casing', casing: {
artistCasing: 'Artist casing', nothing: 'Manter inalterado',
casing: { lower: 'minusculas',
nothing: 'Manter inalterado', upper: 'MAIÚSCULAS',
lower: 'minusculas', start: 'Início De Cada Palavra',
upper: 'MAIÙSCULAS', sentence: 'Como uma frase'
start: 'Ínicio De Cada Palavra', },
sentence: 'Like a sentence' previewVolume: 'Volume de Pré-visualização',
}, executeCommand: {
previewVolume: 'Preview Volume', title: 'Comando a executar após transferir',
executeCommand: { description: 'Deixar em branco para nenhuma acção'
title: 'Comando a executar após transferir', }
description: 'Deixar em branco para nenhuma acção' },
} spotify: {
}, title: 'Funcionalidades Spotify',
spotify: { clientID: 'Spotify clientID',
title: 'Funcionalidades Spotify', clientSecret: 'Spotify Client Secret',
clientID: 'Spotify clientID', username: 'nome de utilizador Spotify'
clientSecret: 'Spotify Client Secret', },
username: 'nome de utilizador Spotify' reset: 'Repor configurações padrão',
}, save: 'Guardar',
reset: 'Reset to Default', toasts: {
save: 'Save', init: 'Configurações carregadas!',
toasts: { update: 'Configurações actualizadas',
init: 'Configurações carregadas!', ARLcopied: 'ARL copiado para area de transferencia'
update: 'Configurações actualizadas', }
ARLcopied: 'ARL copied to clipboard' },
} sidebar: {
}, home: 'início',
sidebar: { search: 'pesquisa',
home: 'início', charts: 'tabelas',
search: 'pesquisa', favorites: 'favoritos',
charts: 'tabelas', linkAnalyzer: 'analizador de links',
favorites: 'favoritos', settings: 'definições',
linkAnalyzer: 'link analyzer', about: 'sobre'
settings: 'definições', },
about: 'sobre' tracklist: {
}, downloadSelection: 'Transferir seleccionados'
tracklist: { }
downloadSelection: 'Descarregar seleccionados'
}
} }
export default pt export default pt

View File

@ -8,24 +8,32 @@ const ru = {
in: 'из {0}', in: 'из {0}',
download_hint: 'Скачать', download_hint: 'Скачать',
play_hint: 'Прослушать', play_hint: 'Прослушать',
toggle_download_tab_hint: 'Показать/Свернуть', toggle_download_tab_hint: 'Показать/Скрыть',
clean_queue_hint: 'Очистить завершённые', clean_queue_hint: 'Очистить завершённые',
cancel_queue_hint: 'Очистить всё', cancel_queue_hint: 'Очистить всё',
cut: 'вырезать',
copy: 'копировать',
copyLink: 'копировать ссылку',
copyImageLink: 'копировать URL картинки',
copyDeezerLink: 'копировать ссылку deezer',
paste: 'вставить',
listTabs: { listTabs: {
empty: '', empty: '',
all: 'все', all: 'все',
top_result: 'лучший результат', top_result: 'лучший результат',
album: 'альбом | альбомы', album: 'альбом | альбомы | альбомы',
artist: 'исполнитель | исполнители', artist: 'исполнитель | исполнители | исполнители',
single: 'сингл | синглы', single: 'сингл | синглы | синглы',
title: 'название | названия', title: 'название',
track: 'трек | треки', track: 'трек | треки | треки',
trackN: '0 треков | {n} трек | {n} трека | {n} треков', trackN: '{n} трек | {n} трека | {n} треков',
releaseN: '0 релизов | {n} релиз | {n} релиза | {n} релизов', releaseN: '{n} релиз | {n} релиза | {n} релизов',
playlist: 'плейлист | плейлисты', playlist: 'плейлист | плейлисты | плейлисты',
compile: 'сборник | сборники', compile: 'сплит | сплиты | сплиты',
ep: 'ep | eps', ep: 'ep',
spotifyPlaylist: 'плейлисты spotify | плейлисты spotify', more: 'Больше альбомов',
featured: 'Представлено в',
spotifyPlaylist: 'плейлист spotify | плейлисты spotify | плейлисты spotify',
releaseDate: 'Дата выхода', releaseDate: 'Дата выхода',
error: 'ошибка' error: 'ошибка'
} }
@ -33,17 +41,17 @@ const ru = {
about: { about: {
titles: { titles: {
usefulLinks: 'Полезные ссылки', usefulLinks: 'Полезные ссылки',
bugReports: 'Баг репорты', bugReports: 'Отчёты об ошибках',
contributing: 'Помощь проекту', contributing: 'Помощь проекту',
donations: 'Пожертвования', donations: 'Пожертвования',
license: 'Лицензия' license: 'Лицензия'
}, },
subtitles: { subtitles: {
bugReports: "Что-то не работает? Скажите нам!", bugReports: "Что-то не работает? Сообщите нам!",
contributing: 'Хотите поддержать проект? Это можно сделать разными способами!', contributing: 'Хотите внести вклад в развитие этого проекта? Это можно сделать разными способами!',
donations: 'Хотите поддержать материально? Можно сделать пожертвование!' donations: 'Хотите поддержать материально? Можно сделать пожертвование!'
}, },
usesLibrary: 'Приложение использует библиотеку <strong>deemix</strong>, с помощью которой вы можете сделать собственный UI deemix.', usesLibrary: 'Приложение использует библиотеку <strong>deemix</strong>, с помощью которой вы можете разработать собственный UI для deemix.',
thanks: `Спасибо <strong>rtonno</strong>, <strong>uhwot</strong> и <strong>lollilol</strong> за помощь с этим проектом, а также <strong>BasCurtiz</strong> и <strong>scarvimane</strong> за иконку.`, thanks: `Спасибо <strong>rtonno</strong>, <strong>uhwot</strong> и <strong>lollilol</strong> за помощь с этим проектом, а также <strong>BasCurtiz</strong> и <strong>scarvimane</strong> за иконку.`,
upToDate: `Следите за последними обновлениями на <a href="https://t.me/RemixDevNews" target="_blank">канале</a> в Telegram.`, upToDate: `Следите за последними обновлениями на <a href="https://t.me/RemixDevNews" target="_blank">канале</a> в Telegram.`,
officialWebsite: 'Официальный сайт', officialWebsite: 'Официальный сайт',
@ -51,46 +59,46 @@ const ru = {
officialWebuiRepo: 'Официальный репозиторий WebUI', officialWebuiRepo: 'Официальный репозиторий WebUI',
officialSubreddit: 'Официальный сабреддит', officialSubreddit: 'Официальный сабреддит',
newsChannel: 'Канал новостей', newsChannel: 'Канал новостей',
questions: `Если у вас возникли вопросы или проблемы с приложением, поищите решение на <a href="https://www.reddit.com/r/deemix" target="_blank">сабреддите</a>. Если решения не нашли, можете создать новый пост и описать вашу проблему.`, questions: `Если у вас возникли вопросы или проблемы с приложением, поищите решение на <a href="https://www.reddit.com/r/deemix" target="_blank">сабреддите</a>. Если не нашли решение, можете создать новый пост и описать вашу проблему.`,
beforeReporting: `Перед тем, как сообщать об ошибках, убедитесь, что у вас стоит последняя версия приложения и что проблема не на вашей стороне.`, beforeReporting: `Перед тем, как сообщать об ошибках, убедитесь, что вы используете последнюю версию приложения и что проблема не на вашей стороне.`,
beSure: `Убедитесь, что ошибка возникает и на других устройствах. Также <strong>НЕ </strong> сообщайте об ошибке, если про неё уже известно.`, beSure: `Убедитесь, что ошибка возникает и на других устройствах. Также <strong>НЕ</strong> сообщайте об ошибке, если про неё уже известно.`,
duplicateReports: 'Повторные сообщения об ошибках рассматриваться не будут.', duplicateReports: 'Повторные сообщения об ошибках рассматриваться не будут.',
dontOpenIssues: `<strong>НЕ НАДО</strong> создавать задачу с простым вопросом, для этого есть сабреддит.`, dontOpenIssues: `<strong>НЕ</strong> используйте репозиторий для вопросов автору, для этого есть сабреддит.`,
newUI: `Если вы хорошо знаете python, то можете сделать новый UI для приложения с использованием базовой библиотеки или пофиксить в ней баги и сделать pull request в <a href="https://codeberg.org/RemixDev/deemix" target="_blank">репозитории</a>.`, newUI: `Если вы хорошо знаете python, то можете сделать новый UI для приложения с использованием базовой библиотеки или пофиксить в ней баги и сделать pull request в <a href="https://codeberg.org/RemixDev/deemix" target="_blank">репозитории</a>.`,
acceptFeatures: `Новые фичи также приветствуются, но не слишком сложные, так как они будут добавлены в приложение, а не в саму библиотеку.`, acceptFeatures: `Можете предложить новые функции, но не слишком сложные, так как они будут добавлены в приложение, а не в саму библиотеку.`,
otherLanguages: `Если вы хорошо знаете другой язык программирования, можете портировать на нём deemix!`, otherLanguages: `Если вы хорошо знаете другой язык программирования, можете портировать на нём deemix!`,
understandingCode: `Не можете понять код? Напишите RemixDev up в Telegram или на Reddit.`, understandingCode: `Не можете разобраться в коде? Свяжитесь с RemixDev в Telegram или на Reddit.`,
contributeWebUI: `Если вы знаете Vue.js (JavaScript), HTML или CSS, можете внести вклад в <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`, contributeWebUI: `Если вы знаете Vue.js (JavaScript), HTML или CSS, можете внести вклад в развитие <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`,
itsFree: `Помните, что это <strong>бесплатное приложение</strong> и вам следует <strong>поддерживать исполнителей</strong>, которые вам нравятся прежде, чем поддерживать разработчиков.`, itsFree: `Помните, что это <strong>бесплатное приложение</strong> и вам следует <strong>поддерживать понравившихся исполнителей</strong> прежде, чем поддерживать разработчиков.`,
notObligated: `Вы не обязаны делать пожертвования, я всё равно вас ценю!`, notObligated: `Вы не обязаны делать пожертвования, я всё равно вас ценю!`,
lincensedUnder: `Проект находится под лицензией lincensedUnder: `Проект распространяется под лицензией
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank" <a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"
>GNU General Public License 3.0</a >GNU General Public License 3.0</a
>.` >.`
}, },
charts: { charts: {
title: 'Чарты', title: 'Чарты',
changeCountry: 'Изменить страну', changeCountry: 'Сменить страну',
download: 'Скачать чарт' download: 'Скачать чарт'
}, },
errors: { errors: {
title: 'Errors for {0}', title: 'Ошибки {0}',
ids: { ids: {
invalidURL: 'URL не распознана', invalidURL: 'URL не распознан',
unsupportedURL: 'URL не поддерживается', unsupportedURL: 'URL не поддерживается',
ISRCnotOnDeezer: 'ISRC трека недоступен на deezer', ISRCnotOnDeezer: 'ISRC данного трека недоступен на Deezer',
notYourPrivatePlaylist: "Нельзя скачивать чужие плейлисты.", notYourPrivatePlaylist: "Вы не можете скачивать чужие приватные плейлисты.",
spotifyDisabled: 'Неправильно настроены параметры Spotify.', spotifyDisabled: 'Неправильно настроены параметры Spotify.',
trackNotOnDeezer: 'Трек не найден на deezer!', trackNotOnDeezer: 'Трек не найден на Deezer!',
albumNotOnDeezer: 'Альбом не найден deezer!', albumNotOnDeezer: 'Альбом не найден на Deezer!',
notOnDeezer: 'Трек недоступен на Deezer!', notOnDeezer: 'Трек недоступен на Deezer!',
notEncoded: 'Трек ещё не перекодирован!', notEncoded: 'Трек ещё не перекодирован!',
notEncodedNoAlternative: 'Трек не перекодирован, альтернатив не найдено!', notEncodedNoAlternative: 'Трек не перекодирован, альтернатив не найдено!',
wrongBitrate: 'Не найден трек с нужным битрейтом.', wrongBitrate: 'Данного трека нет в нужном битрейте.',
wrongBitrateNoAlternative: 'Не найден трек с нужным битрейтом. Альтернатив не найдено!', wrongBitrateNoAlternative: 'Данного трека нет в нужном битрейте. Альтернатив не найдено!',
no360RA: 'Трек недоступен в Reality Audio 360.', no360RA: 'Трек недоступен в формате Reality Audio 360.',
notAvailable: "Трек недоступен на серверах deezer!", notAvailable: "Трек недоступен на серверах Deezer!",
notAvailableNoAlternative: "Трек недоступен на серверах deezer. Альтернатив не найдено!" notAvailableNoAlternative: "Трек недоступен на серверах Deezer. Альтернатив не найдено!"
} }
}, },
favorites: { favorites: {
@ -101,7 +109,7 @@ const ru = {
noTracks: 'Избранные треки не найдены' noTracks: 'Избранные треки не найдены'
}, },
home: { home: {
needTologin: 'Вам нужно зайти под своим Deezer аккаунтом прежде, чем скачивать.', needTologin: 'Вам необходимо войти под своей учетной записью Deezer, прежде чем вы сможете скачивать.',
openSettings: 'Открыть настройки', openSettings: 'Открыть настройки',
sections: { sections: {
popularPlaylists: 'Популярные плейлисты', popularPlaylists: 'Популярные плейлисты',
@ -109,9 +117,9 @@ const ru = {
} }
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'Используйте этот раздел, чтобы узнать информацию о ссылке, по которой вы хотите скачать.', info: 'Используйте этот раздел, чтобы узнать информацию о ссылке, которую требуется скачать.',
useful: useful:
"Этот раздел нужен, если вы хотите скачать треки, недоступные в вашей стране, а также посмотреть, где они доступны.", "Этот раздел нужен, если вы хотите загрузить треки, недоступные в вашей стране, а также посмотреть, где они доступны.",
linkNotSupported: 'Ссылка не поддерживается', linkNotSupported: 'Ссылка не поддерживается',
linkNotSupportedYet: 'Эта ссылка не поддерживается, попробуйте вставить другую.', linkNotSupportedYet: 'Эта ссылка не поддерживается, попробуйте вставить другую.',
table: { table: {
@ -123,7 +131,7 @@ const ru = {
trackNumber: 'Номер трека', trackNumber: 'Номер трека',
releaseDate: 'Дата выхода', releaseDate: 'Дата выхода',
bpm: 'BPM', bpm: 'BPM',
label: 'Издатель', label: 'Издатедь',
recordType: 'Тип', recordType: 'Тип',
genres: 'Жанр', genres: 'Жанр',
tracklist: 'Треклист' tracklist: 'Треклист'
@ -144,21 +152,22 @@ const ru = {
downloads: 'загрузки', downloads: 'загрузки',
toasts: { toasts: {
addedToQueue: '{0} добавлено в очередь', addedToQueue: '{0} добавлено в очередь',
alreadyInQueue: '{0} уже есть в очереди!', alreadyInQueue: '{0} уже присутствует в очереди!',
finishDownload: '{0} загрузок завершено.', finishDownload: 'Загрузка {0} завершена.',
allDownloaded: 'Все загрузки завершены!', allDownloaded: 'Все загрузки завершены!',
refreshFavs: 'Обновление завершено!', refreshFavs: 'Обновление завершено!',
loggingIn: 'Вход', loggingIn: 'Вход',
loggedIn: 'Вход выполнен', loggedIn: 'Вход выполнен',
alreadyLogged: 'Вход уже выполнен', alreadyLogged: 'Вход уже выполнен',
loginFailed: "Вход не выполнен", loginFailed: "Вход не выполнен",
loggedOut: 'Logged out', loggedOut: 'Вы вышли из аккаунта',
cancellingCurrentItem: 'Отмена закачки.', cancellingCurrentItem: 'Отмена текущей загрузки.',
currentItemCancelled: 'Отменено.', currentItemCancelled: 'Отменено.',
startAddingArtist: 'Добавление {0} альбомов в очередь', startAddingArtist: 'Добавление альбомов {0} в очередь',
finishAddingArtist: 'Добавлено {0} альбомов в очередь', finishAddingArtist: 'Альбомы {0} добавлены в очередь',
startConvertingSpotifyPlaylist: 'Преобразование треков из spotify в deezer', startConvertingSpotifyPlaylist: 'Добавление плейлиста Spotify в очередь',
finishConvertingSpotifyPlaylist: 'Преобразование Spotify playlist converted' finishConvertingSpotifyPlaylist: 'Spotify плейлист добавлен в очередь',
loginNeededToDownload: 'Войдите в аккаунт, чтобы скачивать треки!'
}, },
settings: { settings: {
title: 'Настройки', title: 'Настройки',
@ -174,10 +183,10 @@ const ru = {
}, },
appearance: { appearance: {
title: 'Внешний вид', title: 'Внешний вид',
slimDownloadTab: 'Обрезать вкладку с загрузками' slimDownloadTab: 'Компактная вкладка с загрузками'
}, },
downloadPath: { downloadPath: {
title: 'Путь сохранения' title: 'Путь для сохранения'
}, },
templates: { templates: {
title: 'Шаблоны', title: 'Шаблоны',
@ -187,27 +196,27 @@ const ru = {
}, },
folders: { folders: {
title: 'Папки', title: 'Папки',
createPlaylistFolder: 'Создать папки для плейлистов', createPlaylistFolder: 'Создавать папки для плейлистов',
playlistNameTemplate: 'Название папки плейлиста', playlistNameTemplate: 'Название папки плейлиста',
createArtistFolder: 'Создать папки для исполнителя', createArtistFolder: 'Создавать папки для исполнителя',
artistNameTemplate: 'Название папки исполнителя', artistNameTemplate: 'Название папки исполнителя',
createAlbumFolder: 'Создать папки для альбома', createAlbumFolder: 'Создавать папки для альбома',
albumNameTemplate: 'Название папки альбома', albumNameTemplate: 'Название папки альбома',
createCDFolder: 'Создать папки для CD', createCDFolder: 'Создавать папки для CD',
createStructurePlaylist: 'Создать структуру папок для плейлистов', createStructurePlaylist: 'Создавать структуру папок для плейлистов',
createSingleFolder: 'Создать структуру папок для синглов' createSingleFolder: 'Создавать структуру папок для синглов'
}, },
trackTitles: { trackTitles: {
title: 'Названия треков', title: 'Названия треков',
padTracks: 'Добавлять нули', padTracks: 'Добавлять ноль к номерам треков (01, 02, ...)',
paddingSize: 'Количество цифр', paddingSize: 'Кол-во цифр в номере',
illegalCharacterReplacer: 'Замена для запрещённых символов' illegalCharacterReplacer: 'Замена для запрещённых в имени символов'
}, },
downloads: { downloads: {
title: 'Загрузки', title: 'Загрузки',
queueConcurrency: 'Количество одновременных закачек', queueConcurrency: 'Количество одновременных загрузок',
maxBitrate: { maxBitrate: {
title: 'Битрейт', title: 'Предпочитаемый битрейт',
9: 'FLAC 1411kbps', 9: 'FLAC 1411kbps',
3: 'MP3 320kbps', 3: 'MP3 320kbps',
1: 'MP3 128kbps' 1: 'MP3 128kbps'
@ -216,25 +225,26 @@ const ru = {
title: 'Нужно ли перезаписывать файлы?', title: 'Нужно ли перезаписывать файлы?',
y: 'Да, перезаписать файл', y: 'Да, перезаписать файл',
n: "Нет, не перезаписывать", n: "Нет, не перезаписывать",
t: 'Обновить только теги' t: 'Обновить только теги',
b: 'Нет, оставить оба файла и добавить номер к дубликату'
}, },
fallbackBitrate: 'Скачивать с низким битрейтом, если текущий недоступен', fallbackBitrate: 'Загружать с битрейтом ниже, если текущий недоступен',
fallbackSearch: 'Искать другой трек, если нужный недоступен', fallbackSearch: 'Искать похожий трек, если запрашиваемый недоступен',
logErrors: 'Создать логи для ошибок', logErrors: 'Сохранять логи ошибок',
logSearched: 'Создать лог поиска', logSearched: 'Сохранять лог истории поиска',
createM3U8File: 'Создать файлы плейлистов', createM3U8File: 'Создавать файлы плейлистов',
syncedLyrics: 'Создать .lyr файлы (Синхронизированный текст)', syncedLyrics: 'Создать .lyr файлы (синхронизированная лирика)',
playlistFilenameTemplate: 'Шаблон названия плейлиста', playlistFilenameTemplate: 'Шаблон названия плейлиста',
saveDownloadQueue: 'Сохранять текущий список загрузок при закрытии приложения' saveDownloadQueue: 'Сохранять текущую очередь загрузок при закрытии приложения'
}, },
covers: { covers: {
title: 'Обложки', title: 'Обложки',
saveArtwork: 'Сохранять обложки', saveArtwork: 'Сохранять файл обложки',
coverImageTemplate: 'Шаблон названия обложки', coverImageTemplate: 'Шаблон названия обложки',
saveArtworkArtist: 'Сохранять изображение исполнителя', saveArtworkArtist: 'Сохранять файл изображения исполнителя',
artistImageTemplate: 'Шаблон названия изображения', artistImageTemplate: 'Шаблон названия изображения',
localArtworkSize: 'Размер сохраненной обложки', localArtworkSize: 'Размер сохраненной обложки',
embeddedArtworkSize: 'Размер встроенной', embeddedArtworkSize: 'Размер встроенной в теги обложки',
localArtworkFormat: { localArtworkFormat: {
title: 'В каком формате сохранять обложки?', title: 'В каком формате сохранять обложки?',
jpg: 'jpeg', jpg: 'jpeg',
@ -257,23 +267,23 @@ const ru = {
genre: 'Жанр', genre: 'Жанр',
year: 'Год', year: 'Год',
date: 'Дата', date: 'Дата',
explicit: 'Нецензурная лирика', explicit: 'Метка о нецензурной лексике',
isrc: 'ISRC', isrc: 'Номер записи (ISRC)',
length: 'Продолжительность', length: 'Продолжительность',
barcode: 'Штрихкод альбома (UPC)', barcode: 'Уникальный код альбома (UPC)',
bpm: 'BPM', bpm: 'BPM',
replayGain: 'Replay Gain', replayGain: 'Replay Gain',
label: 'Издатель', label: 'Издатель',
lyrics: 'Несинхронизированный текст', lyrics: 'Текст песни',
copyright: 'Права', copyright: 'Права (копирайт)',
composer: 'Композитор', composer: 'Композитор',
involvedPeople: 'Вовлечённые люди' involvedPeople: 'Вовлечённые люди'
}, },
other: { other: {
title: 'Разное', title: 'Разное',
savePlaylistAsCompilation: 'Сохранить плейлисты как сборники', savePlaylistAsCompilation: 'Сохранять плейлисты как сборники',
useNullSeparator: 'Использовать нулевой символ в качестве разделителя', useNullSeparator: 'Использовать null в качестве разделителя',
saveID3v1: 'Дополнительно сохранять ID3v1', saveID3v1: 'Сохранять ID3v1',
multiArtistSeparator: { multiArtistSeparator: {
title: 'Как разделять несколько исполнителей?', title: 'Как разделять несколько исполнителей?',
nothing: 'Сохранить только основного', nothing: 'Сохранить только основного',
@ -282,21 +292,21 @@ const ru = {
using: 'Используя "{0}"' using: 'Используя "{0}"'
}, },
singleAlbumArtist: 'Сохранить только основного исполнителя альбома', singleAlbumArtist: 'Сохранить только основного исполнителя альбома',
albumVariousArtists: 'Оставить "Various Artists" в Исполнителях льбома', albumVariousArtists: 'Оставить "Various Artists" в исполнителях альбома',
removeAlbumVersion: 'Удалить "Album Version" из названия трека', removeAlbumVersion: 'Удалить "Album Version" из названия трека',
removeDuplicateArtists: 'Удалить повторяющихся исполнителей', removeDuplicateArtists: 'Удалить повторяющихся исполнителей',
dateFormat: { dateFormat: {
title: 'Формат даты для FLAC файлов', title: 'Формат даты для FLAC файлов',
year: 'YYYY', year: 'ГГГГ',
month: 'MM', month: 'ММ',
day: 'DD' day: 'ДД'
}, },
featuredToTitle: { featuredToTitle: {
title: 'Что делать с приглашёнными исполнителями?', title: 'Что делать с приглашёнными исполнителями (feat.)?',
0: 'Ничего', 0: 'Ничего',
1: 'Удалить их из названия', 1: 'Удалить из названия трека',
3: 'Удалить из названия и названия альбома', 3: 'Удалить из названия трека и альбома',
2: 'Добавить в название' 2: 'Добавить в название трека'
}, },
titleCasing: 'Регистр названия', titleCasing: 'Регистр названия',
artistCasing: 'Регистр исполнителя', artistCasing: 'Регистр исполнителя',
@ -309,12 +319,12 @@ const ru = {
}, },
previewVolume: 'Громкость прослушивания', previewVolume: 'Громкость прослушивания',
executeCommand: { executeCommand: {
title: 'Выполнить команды по окончании загрузок', title: 'Выполнять команды по окончании загрузок',
description: 'Оставьте пустым, если ничего не требуется' description: 'Оставьте пустым, если ничего не требуется'
} }
}, },
spotify: { spotify: {
title: 'Функции Spotify', title: 'Настройки Spotify',
clientID: 'Spotify clientID', clientID: 'Spotify clientID',
clientSecret: 'Spotify Client Secret', clientSecret: 'Spotify Client Secret',
username: 'Spotify username' username: 'Spotify username'
@ -328,11 +338,11 @@ const ru = {
} }
}, },
sidebar: { sidebar: {
home: 'домой', home: 'главная',
search: 'поиск', search: 'поиск',
charts: 'чарты', charts: 'чарты',
favorites: 'избранное', favorites: 'избранное',
linkAnalyzer: 'просмотр ссылок', linkAnalyzer: 'анализ ссылок',
settings: 'настройки', settings: 'настройки',
about: 'о проекте' about: 'о проекте'
}, },

345
src/lang/vn.js Normal file
View File

@ -0,0 +1,345 @@
const vn = {
globals: {
welcome: 'Chào mừng đến với deemix',
back: 'trở lại',
loading: 'đang tải',
download: 'Tải xuống {0}',
by: 'bởi {0}',
in: 'trong {0}',
download_hint: 'Tải xuống',
play_hint: 'Phát',
toggle_download_tab_hint: 'Mở rộng/Giấu',
clean_queue_hint: 'Xóa những file đã tải xong',
cancel_queue_hint: 'Hủy tất cả',
listTabs: {
empty: '',
all: 'tất cả',
top_result: 'kết quả hàng đầu',
album: 'album | album',
artist: 'Nghệ sĩ | Nghệ sĩ',
single: 'đơn | đơn',
title: 'tiêu đề | tiêu đề',
track: 'Bài hát | Bài hát',
trackN: '0 Bài hát | {n} Bài hát | {n} Bài hát',
releaseN: '0 sản phẩm | {n} sản phẩm | {n} sản phẩm',
playlist: 'playlist | playlist',
compile: 'tổng hợp | tổng hợp',
ep: 'ep | ep',
spotifyPlaylist: 'playlist của spotify | playlist của spotify',
releaseDate: 'ngày phát hành',
error: 'lỗi'
}
},
about: {
titles: {
usefulLinks: 'Link hữu dụng',
bugReports: 'Báo lỗi',
contributing: 'Đóng góp',
donations: 'Quyên góp',
license: 'Bằng phép'
},
subtitles: {
bugReports: "Bạn thấy có gì đó không hoạt động trong deemix? Xin hãy báo với chúng tôi!",
contributing: 'Bạn muốn đóng góp cho dự án này? Bạn có thể làm điều đó với nhiều cách khác nhau!',
donations: 'Bạn muốn ủng hộ kinh phí? Bạn có thể quyên góp tại đây!'
},
usesLibrary: 'Ứng dụng này sử dụng thư viện <strong>deemix</strong>, bạn có thể dùng nó để tạo một UI riêng cho deemix.',
thanks: `Cảm ơn <strong>rtonno</strong>, <strong>uhwot</strong> và <strong>lollilol</strong> đã giúp tôi với dự án này và <strong>BasCurtiz</strong> và <strong>scarvimane</strong> với việc thiết kế biểu tượng.`,
upToDate: `Cập nhật app bằng cách theo dõi <a href="https://t.me/RemixDevNews" target="_blank">kênh tin tức</a> trên Telegram.`,
officialWebsite: 'Website chính thức',
officialRepo: 'Repo thư viện chính thức',
officialWebuiRepo: 'Repo WebUI chính thức',
officialSubreddit: 'Subreddit chính thức',
newsChannel: 'Kênh tin tức',
questions: `Nếu bạn có câu hỏi hoặc vấn đề về ứng dụng này, xin hãy tìm giải pháp trên <a href="https://www.reddit.com/r/deemix" target="_blank">subreddit</a> trước. Sau đó, nếu bạn không tìm được gì thì bạn có thể tạo một bài đăng về vấn đề của bạn trên subreddit dó.`,
beforeReporting: `Trước khi báo lỗi hãy đảm bảo bạn đang sử dụng phiên bản mới nhất của ứng dụng và lỗi bạn đang gặp không phải là do bạn.`,
beSure: `Hãy đảm bảo là lỗi này vẫn có thể xảy ra trên các thiết bị khác và <strong>XIN ĐỪNG</strong> báo lỗi đã được báo rồi.`,
duplicateReports: 'Những bản báo lỗi trùng nhau sẽ bị đóng, xin bạn hãy để ý điều này.',
dontOpenIssues: `<strong>XIN ĐỪNG</strong> mở vấn đề để hỏi, bạn có thể dùng subreddit trên cho việc đó.`,
newUI: `Nếu bạn thành thạo với python bạn có thể tạo một UI mới bằng cách sử dụng thư viện gốc, hoặc sửa lỗi trong thư viện đó với một pull request trên <a href="https://codeberg.org/RemixDev/deemix" target="_blank">repo này</a>.`,
acceptFeatures: `Tôi có chấp nhận yêu cầu về tính năng mới nhưng không quá phức tạp bởi vì chúng có thể được triển khai trực tiếp vào ứng dụng thay vì vào thư viện.`,
otherLanguages: `Nếu bạn thành thạo với một ngôn ngữ khác, bạn có thể port deemix sang ngôn ngữ đó!`,
understandingCode: `Bạn muốn hiểu code của deemix? Xin hãy liên lạc RemixDev trên Telegram hoặc Reddit.`,
contributeWebUI: `Nếu bạn biết Vue.js (JavaScript), HTML hoặc CSS, bạn có thể góp phần phát triển <a href="https://codeberg.org/RemixDev/deemix-webui" target="_blank">WebUI</a>.`,
itsFree: `Bạn nên nhớ rằng <strong>đây là một dự án phi lợi nhuận</strong> và <strong>bạn nên ủng hộ những Nghệ sĩ yêu thích của bạn</strong> trước khi ủng hộ nhà phát triển.`,
notObligated: `Đừng nghĩ rằng bạn phải đóng góp tiền, tôi vẫn sẽ rất biết ơn bạn!`,
lincensedUnder: `Dự án này được cấp phép bởi
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"
>GNU General Public License 3.0</a
>.`
},
charts: {
title: 'Bảng xếp hạng',
changeCountry: 'Thay đổi quốc gia',
download: 'Tải xuống bảng xếp hạng này'
},
errors: {
title: 'Lỗi {0}',
ids: {
invalidURL: 'Không nhận diện được URL',
unsupportedURL: 'URL này chưa được hỗ trợ',
ISRCnotOnDeezer: 'ISRC của bài hát này hiện không có trên Deezer',
notYourPrivatePlaylist: "Bạn không thể tải xuống playlist riêng của người khác.",
spotifyDisabled: 'Chức năng Spotify chưa được thiết lập đúng cách.',
trackNotOnDeezer: 'Bài hát không có trên Deezer!',
albumNotOnDeezer: 'Album không có trên Deezer!',
notOnDeezer: 'Bài hát chưa có trên Deezer!',
notEncoded: 'Bài hát chưa được encode!',
notEncodedNoAlternative: 'Bài hát chưa được encode và không có bản thay thế nào khác!',
wrongBitrate: 'Bài hát này không có ở bitrate bạn muốn.',
wrongBitrateNoAlternative: 'Bài hát này không có ở bitrate bạn muốn và không có bản thay thế nào khác!',
no360RA: 'Bài hát này không có ở dạng Reality Audio 360.',
notAvailable: "Bài hát này không có trên server của Deezer!",
notAvailableNoAlternative: "Bài hát này không có trên server của Deezer và không có bản thay thế nào khác!"
}
},
favorites: {
title: 'Yêu thích',
noPlaylists: 'Không tìm được Playlist',
noAlbums: 'Không tìm được Album Yêu thích',
noArtists: 'Không tìm được Nghệ sĩ Yêu thích',
noTracks: 'Không tìm được Bài hát Yêu thích'
},
home: {
needTologin: 'Bạn cần phải đăng nhập vào tài khoản Deezer trước khi bắt đầu tải xuống.',
openSettings: 'Mở Cài đặt',
sections: {
popularPlaylists: 'Playlist Nổi tiếng',
popularAlbums: 'Album được stream nhiều nhất'
}
},
linkAnalyzer: {
info: 'Bạn có thể sử dụng chức năng này để kiếm thêm thông tin về đường link mà bạn muốn tải xuống.',
useful:
"Chức năng này rất hữu dụng nếu bạn muốn tải các bài hát hiện không có sẵn ở quốc gia của bạn và muốn biết các quốc gia được hỗ trợ.",
linkNotSupported: 'Đường link này chưa được hỗ trợ',
linkNotSupportedYet: 'Đường link này chưa được hỗ trợ, xin hãy thử lại với một đường link khác.',
table: {
id: 'ID',
isrc: 'ISRC',
upc: 'UPC',
duration: 'Thời lượng',
diskNumber: 'Số đĩa',
trackNumber: 'Số bài hát',
releaseDate: 'Ngày phát hành',
bpm: 'BPM',
label: 'Hãng',
recordType: 'Loại Thu âm',
genres: 'Thể loại',
tracklist: 'Danh sách các bài hát'
}
},
search: {
startSearching: 'Bắt đầu tìm kiếm!',
description:
'Bạn có thể tìm một bài hát, album, nghệ sĩ, playlist, v.v...! Bạn cũng có thể dùng link của Deezer',
fans: '{0} người hâm mộ',
noResults: 'Không có kết quả',
noResultsTrack: 'Không tìm được bài hát nào',
noResultsAlbum: 'Không tìm được album nào',
noResultsArtist: 'Không tìm được nghệ sĩ nào',
noResultsPlaylist: 'Không tìm được playlist nào'
},
searchbar: 'Tìm những gì bạn muốn (bạn cũng có thể sữ dụng một đường link)',
downloads: 'Tải xuống',
toasts: {
addedToQueue: '{0} đã được đưa vào hàng chờ',
alreadyInQueue: '{0} đã đang trong hàng chờ!',
finishDownload: '{0} đã tải xong.',
allDownloaded: 'Tất cả các bài hát đã được tải xuống!',
refreshFavs: 'Tải lại hoàn tất!',
loggingIn: 'Đang đăng nhập',
loggedIn: 'Đăng nhập thành công',
alreadyLogged: 'Đã đăng nhập',
loginFailed: "Không thể đăng nhập",
loggedOut: 'Đăng xuất',
cancellingCurrentItem: 'Đang hủy file hiện tại.',
currentItemCancelled: 'File hiện tại đã bị hủy.',
startAddingArtist: 'Đang đưa {0} album vào hàng chờ',
finishAddingArtist: 'Đã đưa {0} album vào hàng chờ',
startConvertingSpotifyPlaylist: 'Đang chuyển đổi các bài hát từ Spotify sang Deezer',
finishConvertingSpotifyPlaylist: 'Playlist của Spotify đã được chuyển đổi',
loginNeededToDownload: 'Bạn cần phải đang nhập để tải nhạc!'
},
settings: {
title: 'Cài đặt',
languages: 'Ngôn ngữ',
login: {
title: 'Đăng nhập',
loggedIn: 'Bạn đã đăng nhập với tên {username}',
arl: {
question: 'Làm cách nào để có ARL của tôi?',
update: 'Cập nhật ARL'
},
logout: 'Đăng xuất'
},
appearance: {
title: 'Giao diện',
slimDownloadTab: 'Thanh tải xuống nhỏ'
},
downloadPath: {
title: 'Nơi tải xuống'
},
templates: {
title: 'Bản mẫu',
tracknameTemplate: 'Bài hát mẫu',
albumTracknameTemplate: 'Bài hát trong album mẫu',
playlistTracknameTemplate: 'Bài hát trong playlist mẫu'
},
folders: {
title: 'Thư mục',
createPlaylistFolder: 'Tạo thư mục cho playlist',
playlistNameTemplate: 'Thư mục playlist mẫu',
createArtistFolder: 'Tạo thư mục cho nghệ sĩ',
artistNameTemplate: 'Thư mục Nghệ sĩ mẫu',
createAlbumFolder: 'Tạo thư mục cho album',
albumNameTemplate: 'Thư mục cho album mẫu',
createCDFolder: 'Tạo thư mục cho đĩa CD',
createStructurePlaylist: 'Tạo thư mục có kết cấu cho playlist',
createSingleFolder: 'Tạo thư mục có kết cấu cho đĩa đơn'
},
trackTitles: {
title: 'Tên bài hát',
padTracks: 'Đệm tên bài hát',
paddingSize: 'Ghì đè kích cỡ phần đệm',
illegalCharacterReplacer: 'Thay các kí tự không hợp lệ với'
},
downloads: {
title: 'Tải xuống',
queueConcurrency: 'Số lượng tải xuống cùng lúc',
maxBitrate: {
title: 'Bitrate ưa thích',
9: 'FLAC 1411kbps',
3: 'MP3 320kbps',
1: 'MP3 128kbps'
},
overwriteFile: {
title: 'Tôi có nên ghi đè file này không?',
y: 'Có, hãy ghi đè file này',
n: "Không, đừng ghi đè file này",
t: 'Chỉ ghi đè các tag'
},
fallbackBitrate: 'Bitrate dự phòng',
fallbackSearch: 'Search dự phòng',
logErrors: 'Tạo file log khi có lỗi',
logSearched: 'Tạo file log khi bạn tìm Bài hát',
createM3U8File: 'Tạo file playlist',
syncedLyrics: 'Tạo file .lyr (Lời Bài hát)',
playlistFilenameTemplate: 'Tên playlist mẫu',
saveDownloadQueue: 'Lưu hàng chờ download khi đóng ứng dụng'
},
covers: {
title: 'Bìa album',
saveArtwork: 'Lưu bìa',
coverImageTemplate: 'Tên bìa mẫu',
saveArtworkArtist: 'Lưu hình Nghệ sĩ',
artistImageTemplate: 'Hình nghệ sĩ mẫu',
localArtworkSize: 'Kích cỡ file bìa',
embeddedArtworkSize: 'Kích cỡ bìa trong file bài hát',
localArtworkFormat: {
title: 'Bạn muốn file bìa ở định dạng nào?',
jpg: 'jpg',
png: 'png',
both: 'Cả jpg và png'
},
jpegImageQuality: 'Chất lượng file JPEG'
},
tags: {
head: 'Những tag sẽ được lưu',
title: 'Tiêu đề',
artist: 'Nghệ sĩ',
album: 'Album',
cover: 'Bìa',
trackNumber: 'Số bài hát',
trackTotal: 'Tổng số bài hát',
discNumber: 'Số đĩa',
discTotal: 'Tổng số đĩa',
albumArtist: 'Nghệ sĩ của album',
genre: 'Thể loại',
year: 'Năm',
date: 'Ngày',
explicit: 'Lời explicit',
isrc: 'ISRC',
length: 'Thời lượng',
barcode: 'Mã vạch của album (UPC)',
bpm: 'BPM',
replayGain: 'ReplayGain',
label: 'Nhãn hiệu album',
lyrics: 'Lời',
copyright: 'Bản quyền',
composer: 'Nhà soạn nhạc',
involvedPeople: 'Những người liên quan'
},
other: {
title: 'Khác',
savePlaylistAsCompilation: 'Lưu playlist dưới dạng tuyển tập',
useNullSeparator: 'Dùng dải phân cách null',
saveID3v1: 'Lưu ID3v1',
multiArtistSeparator: {
title: 'Bạn muốn phân cách các nghệ sĩ như thế nào?',
nothing: 'Chỉ lưu nghệ sĩ chính',
default: 'Dùng quy cách tiêu chuẩn',
andFeat: 'Dùng & và feat.',
using: 'Dùng "{0}"'
},
singleAlbumArtist: 'Chỉ lưu Nghệ sĩ Album chính',
albumVariousArtists: 'Giữ nguyên "Nhiều Nghệ sĩ" trong Nghệ sĩ Album',
removeAlbumVersion: 'Bỏ "Phiên bản Album" khỏi tên bài hát',
removeDuplicateArtists: 'Bỏ các tên nghệ sĩ phối hợp',
dateFormat: {
title: 'Định dạng ngày cho file FLAC ',
year: 'YYYY',
month: 'MM',
day: 'DD'
},
featuredToTitle: {
title: 'Tôi nên làm gì với các nghệ sĩ đóng góp?',
0: 'Không làm gì cả',
1: 'Bỏ chúng khỏi tên bài hát',
3: 'Bỏ chúng khỏi tên bài hát và tên album',
2: 'Đưa chúng vào tên bài hát'
},
titleCasing: 'Định dạng tên bài hát',
artistCasing: 'Định dạng tên nghệ sĩ',
casing: {
nothing: 'Không đổi',
lower: 'chữ thường',
upper: 'CHỮ HOA',
start: 'Viết Hoa Ở Chữ Cái Đầu Tiên Của Mỗi Từ',
sentence: 'Như một câu'
},
previewVolume: 'Âm lượng nghe thử',
executeCommand: {
title: 'Thực hiện những lệnh này khi đã tải xuống xong',
description: 'Để trống nếu bạn không muốn thực hiện lệnh nào'
}
},
spotify: {
title: 'Chức năng Spotify',
clientID: 'ClientID của Spotify',
clientSecret: 'Client Secret của Spotify',
username: 'Tên tài khoản của Spotify'
},
reset: 'Quay trở lại cài đặt mặc định',
save: 'Lưu',
toasts: {
init: 'Cài đặt đã được thiết lập!',
update: 'Cài đặt cập nhật thành công!',
ARLcopied: 'ARL đã được sao chép vào clipboard'
}
},
sidebar: {
home: 'trang chủ',
search: 'tìm kiếm',
charts: 'bảng xếp hạng',
favorites: 'yêu thích',
linkAnalyzer: 'phân tích link',
settings: 'cài đặt',
about: 'thông tin'
},
tracklist: {
downloadSelection: 'Tải xuống những mục đã chọn'
}
}
export default vn

View File

@ -9,9 +9,12 @@ import de from '@/lang/de'
import fr from '@/lang/fr' import fr from '@/lang/fr'
import id from '@/lang/id' import id from '@/lang/id'
import pt from '@/lang/pt-pt' import pt from '@/lang/pt-pt'
import ptBr from '@/lang/pt-br' import pt_br from '@/lang/pt-br'
import ru from '@/lang/ru' import ru from '@/lang/ru'
import tr from '@/lang/tr' import tr from '@/lang/tr'
import vn from '@/lang/vn'
import hr from '@/lang/hr'
import ar from '@/lang/ar'
Vue.use(VueI18n) Vue.use(VueI18n)
@ -27,9 +30,12 @@ const locales = {
fr, fr,
id, id,
pt, pt,
ptBr, pt_br,
ru, ru,
tr tr,
vn,
hr,
ar
} }
const i18n = new VueI18n({ const i18n = new VueI18n({
@ -43,25 +49,22 @@ const i18n = new VueI18n({
* @returns a final choice index to select plural word by * @returns a final choice index to select plural word by
*/ */
ru: function(choice, choicesLength) { ru: function(choice, choicesLength) {
if (choice === 0) {
return 0
}
var n = Math.abs(choice) % 100 var n = Math.abs(choice) % 100
var n1 = n % 10 var n1 = n % 10
if (n > 10 && n < 20) { if (n > 10 && n < 20) {
return 3
}
if (n1 > 1 && n1 < 5) {
return 2 return 2
} }
if (n1 == 1) { if (n1 > 1 && n1 < 5) {
return 1 return 1
} }
return 3 if (n1 == 1) {
return 0
}
return 2
} }
} }
}) })

View File

@ -18,6 +18,12 @@
transition: width 0.3s linear; transition: width 0.3s linear;
} }
.converting {
background-color: var(--secondary-color);
-webkit-transition: none !important;
transition: none !important;
}
.indeterminate { .indeterminate {
background-color: var(--accent-color); background-color: var(--accent-color);

View File

@ -15,6 +15,7 @@ html[data-theme='light'] {
--foreground: hsl(0, 0%, 20%); --foreground: hsl(0, 0%, 20%);
--foreground-inverted: hsl(0, 0%, 93%); --foreground-inverted: hsl(0, 0%, 93%);
--accent-color: hsl(210, 100%, 52%); --accent-color: hsl(210, 100%, 52%);
--secondary-color: hsl(46, 100%, 57%);
--panels-background: hsl(210, 3%, 14%); --panels-background: hsl(210, 3%, 14%);
--panels-text: hsl(0, 0%, 100%); --panels-text: hsl(0, 0%, 100%);
--accent-text: hsl(0, 0%, 0%); --accent-text: hsl(0, 0%, 0%);
@ -35,6 +36,7 @@ html[data-theme='dark'] {
--foreground: hsl(0, 0%, 93%); --foreground: hsl(0, 0%, 93%);
--foreground-inverted: hsl(0, 0%, 20%); --foreground-inverted: hsl(0, 0%, 20%);
--accent-color: hsl(210, 100%, 52%); --accent-color: hsl(210, 100%, 52%);
--secondary-color: hsl(46, 100%, 57%);
--panels-background: hsl(0, 0%, 10%); --panels-background: hsl(0, 0%, 10%);
--panels-text: hsl(0, 0%, 100%); --panels-text: hsl(0, 0%, 100%);
--accent-text: hsl(0, 0%, 87%); --accent-text: hsl(0, 0%, 87%);
@ -55,6 +57,7 @@ html[data-theme='purple'] {
--foreground: hsl(0, 0%, 93%); --foreground: hsl(0, 0%, 93%);
--foreground-inverted: hsl(258, 62%, 8%); --foreground-inverted: hsl(258, 62%, 8%);
--accent-color: hsl(261, 85%, 37%); --accent-color: hsl(261, 85%, 37%);
--secondary-color: hsl(46, 100%, 57%);
--panels-background: hsl(257, 70%, 9%); --panels-background: hsl(257, 70%, 9%);
--panels-text: hsl(0, 0%, 100%); --panels-text: hsl(0, 0%, 100%);
--accent-text: hsl(0, 0%, 87%); --accent-text: hsl(0, 0%, 87%);

View File

@ -112,6 +112,17 @@ button {
} }
} }
&.only_icon {
min-width: 24px;
width: 48px;
margin: 0px 0px 0px 8px;
padding: 0px 4px;
i {
padding: 6px 0px;
}
}
&:active { &:active {
background-color: var(--accent-color); background-color: var(--accent-color);
transform: scale(0.98); transform: scale(0.98);

View File

@ -21,21 +21,10 @@
margin: 8px 0px; margin: 8px 0px;
} }
#login_input_arl { .inline-flex input {
margin-bottom: 0px; margin-bottom: 0px;
} }
#settings_btn_copyArl {
min-width: 24px;
width: 48px;
margin: 0px 0px 0px 8px;
padding: 0px 4px;
i {
padding: 6px 0px;
}
}
#spotify_icon { #spotify_icon {
width: 24px; width: 24px;
height: 24px; height: 24px;

View File

@ -1,9 +1,9 @@
import { socket } from '@/utils/socket' import { socket } from '@/utils/socket'
function sendAddToQueue(url, bitrate = null) { function sendAddToQueue(url, bitrate = null) {
if (url != '') { if (!url) return
socket.emit('addToQueue', { url: url, bitrate: bitrate }, () => {})
} socket.emit('addToQueue', { url, bitrate }, () => {})
} }
export default { export default {

View File

@ -8,6 +8,9 @@ import pt from 'svg-country-flags/svg/pt.svg'
import br from 'svg-country-flags/svg/br.svg' import br from 'svg-country-flags/svg/br.svg'
import ru from 'svg-country-flags/svg/ru.svg' import ru from 'svg-country-flags/svg/ru.svg'
import tr from 'svg-country-flags/svg/tr.svg' import tr from 'svg-country-flags/svg/tr.svg'
import vn from 'svg-country-flags/svg/vn.svg'
import hr from 'svg-country-flags/svg/hr.svg'
import ar from '@/assets/ar.svg'
export default { export default {
it, it,
@ -17,7 +20,10 @@ export default {
fr, fr,
id, id,
pt, pt,
ptBr: br, pt_br: br,
ru, ru,
tr tr,
vn,
hr,
ar
} }

View File

@ -44,6 +44,7 @@ export const toast = function(msg, icon = null, dismiss = true, id = null) {
} }
if (toastObj && dismissable) { if (toastObj && dismissable) {
toastObj.hideToast() toastObj.hideToast()
if (id) delete toastsWithId[id]
} }
} }
}).showToast() }).showToast()

View File

@ -1,3 +1,22 @@
/**
* Climbs the DOM until the root is reached, storing every node passed.
* @param {HTMLElement} el
* @return {Array} Contains all the nodes between el and the root
*/
export function generatePath(el) {
if (!el) {
throw new Error('No element passed to the generatePath function!')
}
let path = [el]
while ((el = el.parentNode) && el !== document) {
path.push(el)
}
return path
}
export function isValidURL(text) { export function isValidURL(text) {
let lowerCaseText = text.toLowerCase() let lowerCaseText = text.toLowerCase()
@ -54,6 +73,24 @@ export function debounce(func, wait, immediate) {
} }
} }
/**
* Workaround to copy to the clipboard cross-OS by generating a
* ghost input and copying the passed String
*
* @param {string} text Text to copy
*/
export function copyToClipboard(text) {
const ghostInput = document.createElement('input')
document.body.appendChild(ghostInput)
ghostInput.setAttribute('type', 'text')
ghostInput.setAttribute('value', text)
ghostInput.select()
ghostInput.setSelectionRange(0, 99999)
document.execCommand('copy')
ghostInput.remove()
}
export const COUNTRIES = { export const COUNTRIES = {
AF: 'Afghanistan', AF: 'Afghanistan',
AX: '\u00c5land Islands', AX: '\u00c5land Islands',