workflow: added linter and linted src/ folder

This commit is contained in:
Roberto Tonino 2021-05-23 18:46:03 +02:00
parent 0f2a1103fd
commit 3a58636d36
61 changed files with 7343 additions and 2498 deletions

15
.eslintrc.yml Normal file
View File

@ -0,0 +1,15 @@
---
extends:
- "@nuxtjs"
- plugin:prettier/recommended
plugins:
- "@typescript-eslint"
parserOptions:
parser: "@typescript-eslint/parser"
rules:
"@typescript-eslint/no-unused-vars":
- error
- args: all
argsIgnorePattern: ^_
no-unused-vars: off
no-console: off

4802
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,8 @@
"minify": "esbuild public/js/bundle.temp.js --outfile=public/js/bundle.js --minify", "minify": "esbuild public/js/bundle.temp.js --outfile=public/js/bundle.js --minify",
"dev": "npm-run-all --parallel serve watch:js", "dev": "npm-run-all --parallel serve watch:js",
"dev:gui": "npm-run-all --parallel serve:gui watch:js", "dev:gui": "npm-run-all --parallel serve:gui watch:js",
"build": "npm-run-all --sequential clean build:js minify clean-temp" "build": "npm-run-all --sequential clean build:js minify clean-temp",
"lint": "eslint src/**/*.{js,vue} --fix"
}, },
"dependencies": { "dependencies": {
"@vue/composition-api": "1.0.0-beta.21", "@vue/composition-api": "1.0.0-beta.21",
@ -25,14 +26,21 @@
"vuex": "^3.6.0" "vuex": "^3.6.0"
}, },
"devDependencies": { "devDependencies": {
"@nuxtjs/eslint-config": "6.0.0",
"@rollup/plugin-alias": "^3.1.1", "@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0", "@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-replace": "^2.3.4", "@rollup/plugin-replace": "^2.3.4",
"@typescript-eslint/eslint-plugin": "4.21.0",
"@typescript-eslint/parser": "4.21.0",
"esbuild": "^0.8.22", "esbuild": "^0.8.22",
"eslint": "7.23.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "3.3.1",
"node-sass": "^5.0.0", "node-sass": "^5.0.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss": "^8.2.1", "postcss": "^8.2.1",
"prettier": "2.2.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rollup": "^2.35.0", "rollup": "^2.35.0",
"rollup-plugin-analyzer": "^3.3.0", "rollup-plugin-analyzer": "^3.3.0",
@ -41,6 +49,7 @@
"rollup-plugin-vue": "4.2.0", "rollup-plugin-vue": "4.2.0",
"sass": "^1.30.0", "sass": "^1.30.0",
"tailwindcss": "^1.9.6", "tailwindcss": "^1.9.6",
"typescript": "4.2.4",
"vue-template-compiler": "^2.6.12" "vue-template-compiler": "^2.6.12"
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -14,7 +14,7 @@
<BaseLoadingPlaceholder <BaseLoadingPlaceholder
text="Connecting to local server..." text="Connecting to local server..."
:hidden="isSocketConnected" :hidden="isSocketConnected"
additionalClasses="absolute top-0 left-0 w-screen h-screen bg-black bg-opacity-50 z-50" additional-classes="absolute top-0 left-0 w-screen h-screen bg-black bg-opacity-50 z-50"
/> />
<TheTrackPreview /> <TheTrackPreview />
@ -52,11 +52,6 @@ import TheContent from '@components/TheContent.vue'
import TheDownloadBar from '@components/downloads/TheDownloadBar.vue' import TheDownloadBar from '@components/downloads/TheDownloadBar.vue'
export default { export default {
data() {
return {
isSocketConnected: false
}
},
components: { components: {
TheSidebar, TheSidebar,
TheSearchBar, TheSearchBar,
@ -68,9 +63,14 @@ export default {
TheContent TheContent
// ConfirmModal // ConfirmModal
}, },
data() {
return {
isSocketConnected: false
}
},
mounted() { mounted() {
socket.addEventListener('open', (event) => { socket.addEventListener('open', event => {
console.log("Connected to WebSocket") console.log('Connected to WebSocket')
this.isSocketConnected = true this.isSocketConnected = true
}) })
} }

View File

@ -81,11 +81,11 @@ document.addEventListener('paste', pasteEvent => {
if (router.currentRoute.name === 'Link Analyzer') { if (router.currentRoute.name === 'Link Analyzer') {
socket.emit('analyzeLink', pastedText) socket.emit('analyzeLink', pastedText)
} else { } else {
if (pastedText.indexOf('\n') != -1) pastedText = pastedText.replace(/\n/g, ';') if (pastedText.includes('\n')) pastedText = pastedText.replace(/\n/g, ';')
sendAddToQueue(pastedText) sendAddToQueue(pastedText)
} }
} else { } else {
let searchbar = document.querySelector('#searchbar') const searchbar = document.querySelector('#searchbar')
searchbar.select() searchbar.select()
searchbar.setSelectionRange(0, 99999) searchbar.setSelectionRange(0, 99999)
} }
@ -140,7 +140,7 @@ function loggedIn(data) {
break break
case -1: case -1:
toast(i18n.t('toasts.deezerNotAvailable'), 'close', true, 'login-toast') toast(i18n.t('toasts.deezerNotAvailable'), 'close', true, 'login-toast')
return
// TODO // TODO
// $('#open_login_prompt').show() // $('#open_login_prompt').show()
// document.getElementById('logged_in_info').classList.add('hide') // document.getElementById('logged_in_info').classList.add('hide')

View File

@ -1,9 +1,9 @@
<template> <template>
<main <main
id="content" id="content"
@scroll="$route.name === 'Search' ? handleContentScroll($event) : null"
ref="content" ref="content"
aria-label="main content" aria-label="main content"
@scroll="$route.name === 'Search' ? handleContentScroll($event) : null"
> >
<div id="container"> <div id="container">
<BackButton v-if="showBackButton" class="sticky -ml-20" style="top: 1rem" /> <BackButton v-if="showBackButton" class="sticky -ml-20" style="top: 1rem" />
@ -11,16 +11,16 @@
<keep-alive> <keep-alive>
<router-view <router-view
v-if="!$route.meta.notKeepAlive" v-if="!$route.meta.notKeepAlive"
:class="{ '-mt-16': showBackButton }"
:key="$route.fullPath" :key="$route.fullPath"
:class="{ '-mt-16': showBackButton }"
:perform-scrolled-search="performScrolledSearch" :perform-scrolled-search="performScrolledSearch"
></router-view> ></router-view>
</keep-alive> </keep-alive>
<router-view <router-view
v-if="$route.meta.notKeepAlive" v-if="$route.meta.notKeepAlive"
:class="{ '-mt-16': showBackButton }"
:key="$route.fullPath" :key="$route.fullPath"
:class="{ '-mt-16': showBackButton }"
:perform-scrolled-search="performScrolledSearch" :perform-scrolled-search="performScrolledSearch"
></router-view> ></router-view>
</div> </div>
@ -83,7 +83,7 @@ export default {
}), }),
computed: { computed: {
showBackButton() { showBackButton() {
return ['Tracklist', 'Artist', 'Album', 'Playlist', 'Spotify Playlist'].indexOf(this.$route.name) !== -1 return ['Tracklist', 'Artist', 'Album', 'Playlist', 'Spotify Playlist'].includes(this.$route.name)
} }
}, },
mounted() { mounted() {

View File

@ -6,6 +6,7 @@
<input <input
id="searchbar" id="searchbar"
ref="searchbar"
class="w-full" class="w-full"
autocomplete="off" autocomplete="off"
type="search" type="search"
@ -13,7 +14,6 @@
value="" value=""
:placeholder="$t('searchbar')" :placeholder="$t('searchbar')"
autofocus autofocus
ref="searchbar"
@keyup="performSearch($event)" @keyup="performSearch($event)"
/> />
<!-- @keyup.enter.exact="onEnter" <!-- @keyup.enter.exact="onEnter"
@ -134,20 +134,20 @@ export default defineComponent({
}, },
methods: { methods: {
async performSearch(keyEvent) { async performSearch(keyEvent) {
let isEnterPressed = keyEvent.keyCode === 13 const isEnterPressed = keyEvent.keyCode === 13
if (!isEnterPressed) return if (!isEnterPressed) return
let term = this.$refs.searchbar.value const term = this.$refs.searchbar.value
let isEmptySearch = term === '' const isEmptySearch = term === ''
if (isEmptySearch) return if (isEmptySearch) return
let isSearchingURL = isValidURL(term) const isSearchingURL = isValidURL(term)
let isCtrlPressed = keyEvent.ctrlKey const isCtrlPressed = keyEvent.ctrlKey
let isShowingAnalyzer = this.$route.name === 'Link Analyzer' const isShowingAnalyzer = this.$route.name === 'Link Analyzer'
let isShowingSearch = this.$route.name === 'Search' const isShowingSearch = this.$route.name === 'Search'
let isSameAsLastSearch = term === this.lastTextSearch const isSameAsLastSearch = term === this.lastTextSearch
if (isSearchingURL) { if (isSearchingURL) {
if (isCtrlPressed) { if (isCtrlPressed) {

View File

@ -217,14 +217,14 @@
const possibleStates = ['converting', 'downloading', 'download finished', 'completed'] const possibleStates = ['converting', 'downloading', 'download finished', 'completed']
export default { export default {
props: {
queueItem: Object
},
data() { data() {
return { return {
isLoading: false isLoading: false
} }
}, },
props: {
queueItem: Object
},
computed: { computed: {
hasFails() { hasFails() {
return this.queueItem.failed >= 1 return this.queueItem.failed >= 1
@ -242,7 +242,7 @@ export default {
return this.queueItem.status === 'download finished' && this.hasFails return this.queueItem.status === 'download finished' && this.hasFails
}, },
isDeterminateStatus() { isDeterminateStatus() {
return possibleStates.indexOf(this.queueItem.status) !== -1 return possibleStates.includes(this.queueItem.status)
}, },
barClass() { barClass() {
return { return {
@ -292,14 +292,12 @@ export default {
if (this.queueItem.status === 'download finished') { if (this.queueItem.status === 'download finished') {
if (!this.hasFails) { if (!this.hasFails) {
text = 'done' text = 'done'
} else { } else if (this.queueItem.failed >= this.queueItem.size) {
if (this.queueItem.failed >= this.queueItem.size) {
text = 'error' text = 'error'
} else { } else {
text = 'warning' text = 'warning'
} }
} }
}
return text return text
} }

View File

@ -1,29 +1,29 @@
<template> <template>
<section <section
id="download_tab_container" id="download_tab_container"
ref="container"
class="block h-screen bg-panels-bg text-foreground" class="block h-screen bg-panels-bg text-foreground"
:class="{ 'tab-hidden': !isExpanded, 'w-8': !isExpanded }" :class="{ 'tab-hidden': !isExpanded, 'w-8': !isExpanded }"
@transitionend="$refs.container.style.transition = ''"
ref="container"
:data-label="$t('downloads')" :data-label="$t('downloads')"
aria-label="downloads" aria-label="downloads"
@transitionend="$refs.container.style.transition = ''"
> >
<!-- Drag handler --> <!-- Drag handler -->
<div <div
v-show="isExpanded" v-show="isExpanded"
class="absolute w-4 h-full bg-grayscale-200" class="absolute w-4 h-full bg-grayscale-200"
@mousedown.prevent="startDrag"
style="cursor: ew-resize" style="cursor: ew-resize"
@mousedown.prevent="startDrag"
></div> ></div>
<!-- Bar toggler --> <!-- Bar toggler -->
<i <i
id="toggle_download_tab" id="toggle_download_tab"
ref="toggler"
class="m-1 text-2xl cursor-pointer material-icons" class="m-1 text-2xl cursor-pointer material-icons"
:class="{ 'ml-1': !isExpanded, 'ml-5': isExpanded }" :class="{ 'ml-1': !isExpanded, 'ml-5': isExpanded }"
@click.prevent="toggleDownloadTab"
ref="toggler"
:title="$t('globals.toggle_download_tab_hint')" :title="$t('globals.toggle_download_tab_hint')"
@click.prevent="toggleDownloadTab"
></i> ></i>
<!-- Queue buttons --> <!-- Queue buttons -->
@ -39,23 +39,23 @@
> >
folder_open folder_open
</i> </i>
<i class="m-1 text-2xl cursor-pointer material-icons" @click="cleanQueue" :title="$t('globals.clean_queue_hint')"> <i class="m-1 text-2xl cursor-pointer material-icons" :title="$t('globals.clean_queue_hint')" @click="cleanQueue">
clear_all clear_all
</i> </i>
<i <i
class="m-1 text-2xl cursor-pointer material-icons" class="m-1 text-2xl cursor-pointer material-icons"
@click="cancelQueue"
:title="$t('globals.cancel_queue_hint')" :title="$t('globals.cancel_queue_hint')"
@click="cancelQueue"
> >
delete_sweep delete_sweep
</i> </i>
</div> </div>
<div v-show="isExpanded" id="download_list" class="w-full pr-2" :class="{ slim: isSlim }" ref="list"> <div v-show="isExpanded" id="download_list" ref="list" class="w-full pr-2" :class="{ slim: isSlim }">
<QueueItem <QueueItem
v-for="item in queueList" v-for="item in queueList"
:queue-item="item"
:key="item.uuid" :key="item.uuid"
:queue-item="item"
@show-errors="showErrorsTab" @show-errors="showErrorsTab"
@remove-item="onRemoveItem" @remove-item="onRemoveItem"
/> />
@ -179,7 +179,7 @@ export default {
.catch(console.error) .catch(console.error)
// Check if download tab has slim entries // Check if download tab has slim entries
if ('true' === localStorage.getItem('slimDownloads')) { if (localStorage.getItem('slimDownloads') === 'true') {
this.$refs.list.classList.add('slim') this.$refs.list.classList.add('slim')
} }
@ -219,9 +219,11 @@ export default {
} = data } = data
console.log({ initQueueList }) console.log({ initQueueList })
const initQueueComplete = Object.values(initQueueList).filter(el => ['completed', 'withErrors', 'failed'].includes(el.status)).map(el => el.uuid) const initQueueComplete = Object.values(initQueueList)
.filter(el => ['completed', 'withErrors', 'failed'].includes(el.status))
.map(el => el.uuid)
console.log({initQueueComplete}) console.log({ initQueueComplete })
if (initQueueComplete && initQueueComplete.length) { if (initQueueComplete && initQueueComplete.length) {
initQueueComplete.forEach(item => { initQueueComplete.forEach(item => {
@ -274,7 +276,7 @@ export default {
const itemIsAlreadyDownloaded = queueItem.downloaded + queueItem.failed == queueItem.size const itemIsAlreadyDownloaded = queueItem.downloaded + queueItem.failed == queueItem.size
if (itemIsAlreadyDownloaded) { if (itemIsAlreadyDownloaded) {
const itemIsNotInCompletedQueue = this.queueComplete.indexOf(queueItem.uuid) == -1 const itemIsNotInCompletedQueue = !this.queueComplete.includes(queueItem.uuid)
this.$set(this.queueList[queueItem.uuid], 'status', 'download finished') this.$set(this.queueList[queueItem.uuid], 'status', 'download finished')
@ -283,7 +285,7 @@ export default {
this.queueComplete.push(queueItem.uuid) this.queueComplete.push(queueItem.uuid)
} }
} else { } else {
const itemIsNotInQueue = this.queue.indexOf(queueItem.uuid) == -1 const itemIsNotInQueue = !this.queue.includes(queueItem.uuid)
if (itemIsNotInQueue) { if (itemIsNotInQueue) {
this.queue.push(queueItem.uuid) this.queue.push(queueItem.uuid)
@ -304,14 +306,14 @@ export default {
// downloaded and failed default to false? // downloaded and failed default to false?
const { uuid, downloaded, failed, progress, conversion, 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.includes(uuid)) {
if (downloaded) { if (downloaded) {
this.queueList[uuid].downloaded++ this.queueList[uuid].downloaded++
} }
if (failed) { if (failed) {
this.queueList[uuid].failed++ this.queueList[uuid].failed++
this.queueList[uuid].errors.push({ message: error, data: data, errid: errid }) this.queueList[uuid].errors.push({ message: error, data, errid })
} }
if (progress) { if (progress) {
@ -324,7 +326,7 @@ export default {
} }
}, },
removeFromQueue(uuid) { removeFromQueue(uuid) {
let index = this.queue.indexOf(uuid) const index = this.queue.indexOf(uuid)
if (index > -1) { if (index > -1) {
this.$delete(this.queue, index) this.$delete(this.queue, index)
@ -340,7 +342,7 @@ export default {
} else { } else {
this.queue = [currentItem] this.queue = [currentItem]
let tempQueueItem = this.queueList[currentItem] const tempQueueItem = this.queueList[currentItem]
this.queueList = {} this.queueList = {}
this.queueList[currentItem] = tempQueueItem this.queueList[currentItem] = tempQueueItem
@ -397,14 +399,14 @@ export default {
this.$set(this.queueList[uuid], 'status', 'downloading') this.$set(this.queueList[uuid], 'status', 'downloading')
}, },
finishDownload(uuid) { finishDownload(uuid) {
let isInQueue = this.queue.indexOf(uuid) > -1 const isInQueue = this.queue.includes(uuid)
if (!isInQueue) return if (!isInQueue) return
this.$set(this.queueList[uuid], 'status', 'download finished') this.$set(this.queueList[uuid], 'status', 'download finished')
toast(this.$t('toasts.finishDownload', { item: this.queueList[uuid].title }), 'done') toast(this.$t('toasts.finishDownload', { item: this.queueList[uuid].title }), 'done')
let index = this.queue.indexOf(uuid) const index = this.queue.indexOf(uuid)
if (index > -1) { if (index > -1) {
this.queue.splice(index, 1) this.queue.splice(index, 1)

View File

@ -1,8 +1,8 @@
<template functional> <template functional>
<div <div
v-show="!props.hidden"
class="flex justify-center items-center flex-col flex-1 h-full" class="flex justify-center items-center flex-col flex-1 h-full"
:class="props.additionalClasses" :class="props.additionalClasses"
v-show="!props.hidden"
> >
<span class="mb-5">{{ props.text || 'Loading...' }}</span> <span class="mb-5">{{ props.text || 'Loading...' }}</span>
@ -58,4 +58,3 @@
} }
} }
</style> </style>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="wrapper" ref="wrapper"> <div ref="wrapper" class="wrapper">
<div class="body animate__animated animate__bounce" ref="body"> <div ref="body" class="body animate__animated animate__bounce">
<h1 style="flex: 1">{{ titleText }}</h1> <h1 style="flex: 1">{{ titleText }}</h1>
<div class="confirm-area"> <div class="confirm-area">

View File

@ -10,10 +10,10 @@
<button <button
role="button" role="button"
aria-label="download" aria-label="download"
v-on="$listeners"
:data-link="link" :data-link="link"
class="absolute p-0 text-center bg-black border-0 rounded-full opacity-0 download_overlay hover:bg-primary" class="absolute p-0 text-center bg-black border-0 rounded-full opacity-0 download_overlay hover:bg-primary"
tabindex="0" tabindex="0"
v-on="$listeners"
> >
<i class="text-white cursor-pointer material-icons" :title="$t('globals.download_hint')">get_app</i> <i class="text-white cursor-pointer material-icons" :title="$t('globals.download_hint')">get_app</i>
</button> </button>

View File

@ -1,9 +1,9 @@
<template> <template>
<i <i
@mouseenter="previewMouseEnter"
@mouseleave="previewMouseLeave"
class="absolute top-0 right-0 flex items-center justify-center w-full h-full text-center text-white transition-opacity duration-200 ease-in-out bg-black bg-opacity-50 rounded opacity-0 material-icons preview_controls" class="absolute top-0 right-0 flex items-center justify-center w-full h-full text-center text-white transition-opacity duration-200 ease-in-out bg-black bg-opacity-50 rounded opacity-0 material-icons preview_controls"
:title="$t('globals.play_hint')" :title="$t('globals.play_hint')"
@mouseenter="previewMouseEnter"
@mouseleave="previewMouseLeave"
> >
play_arrow play_arrow
</i> </i>

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="context-menu" v-show="menuOpen" ref="contextMenu" :style="{ top: yPos, left: xPos }"> <div v-show="menuOpen" ref="contextMenu" class="context-menu" :style="{ top: yPos, left: xPos }">
<button <button
class="btn menu-option"
v-for="option of sortedOptions" v-for="option of sortedOptions"
:key="option.label"
v-show="option.show" v-show="option.show"
:key="option.label"
class="btn menu-option"
@click.prevent="option.action" @click.prevent="option.action"
> >
<span class="menu-option__text">{{ option.label }}</span> <span class="menu-option__text">{{ option.label }}</span>
@ -91,7 +91,7 @@ export default {
} }
} }
let nextValuePosition = Object.values(options).length + 1 const nextValuePosition = Object.values(options).length + 1
downloadQualities.forEach((quality, index) => { downloadQualities.forEach((quality, index) => {
options[quality.objName] = { options[quality.objName] = {
@ -125,9 +125,9 @@ export default {
methods: { methods: {
showSearchbarMenu(url) { showSearchbarMenu(url) {
console.log(url) console.log(url)
let searchbar = document.getElementById("searchbar") const searchbar = document.getElementById('searchbar')
searchbar.dataset.cmLink = url searchbar.dataset.cmLink = url
let contextMenuEvent = { const contextMenuEvent = {
pageX: 115, pageX: 115,
pageY: 57, pageY: 57,
target: searchbar, target: searchbar,

View File

@ -1,5 +1,5 @@
<template> <template>
<div id="modal_quality" class="smallmodal" v-show="open" @click="tryToDownloadTrack($event)" ref="modal"> <div v-show="open" id="modal_quality" ref="modal" class="smallmodal" @click="tryToDownloadTrack($event)">
<div class="smallmodal-content"> <div class="smallmodal-content">
<button class="btn btn-primary quality-button" data-quality-value="9"> <button class="btn btn-primary quality-button" data-quality-value="9">
{{ $t('globals.download', { thing: 'FLAC' }) }} {{ $t('globals.download', { thing: 'FLAC' }) }}

View File

@ -1,5 +1,5 @@
<template> <template>
<audio id="preview-track" @canplay="onCanPlay" @timeupdate="onTimeUpdate" ref="preview"> <audio id="preview-track" ref="preview" @canplay="onCanPlay" @timeupdate="onTimeUpdate">
<source id="preview-track_source" src="" type="audio/mpeg" /> <source id="preview-track_source" src="" type="audio/mpeg" />
</audio> </audio>
</template> </template>
@ -86,7 +86,7 @@ export default {
const { currentTarget: obj } = e const { currentTarget: obj } = e
var icon = obj.tagName == 'I' ? obj : obj.querySelector('i') const icon = obj.tagName == 'I' ? obj : obj.querySelector('i')
if (obj.hasAttribute('playing')) { if (obj.hasAttribute('playing')) {
if (this.$refs.preview.paused) { if (this.$refs.preview.paused) {
@ -133,7 +133,7 @@ export default {
} }
}, },
async stopStackedTabsPreview() { async stopStackedTabsPreview() {
let controls = Array.prototype.slice.call(document.querySelectorAll('.preview_playlist_controls[playing]')) const controls = Array.prototype.slice.call(document.querySelectorAll('.preview_playlist_controls[playing]'))
if (controls.length === 0) return if (controls.length === 0) return
@ -161,4 +161,3 @@ export default {
} }
} }
</script> </script>

View File

@ -5,10 +5,10 @@
<div <div
class="grid w-16 h-16 ml-auto rounded-full cursor-pointer bg-primary text-grayscale-870 place-items-center" class="grid w-16 h-16 ml-auto rounded-full cursor-pointer bg-primary text-grayscale-870 place-items-center"
@click.stop="sendAddToQueue(downloadLink)"
aria-label="download" aria-label="download"
role="button" role="button"
:data-cm-link="downloadLink" :data-cm-link="downloadLink"
@click.stop="sendAddToQueue(downloadLink)"
> >
<i class="text-4xl material-icons" :title="$t('globals.download_hint')">get_app</i> <i class="text-4xl material-icons" :title="$t('globals.download_hint')">get_app</i>
</div> </div>
@ -18,8 +18,8 @@
<BaseTab <BaseTab
v-for="(item, name) in artistReleases" v-for="(item, name) in artistReleases"
:key="name" :key="name"
@click="currentTab = name"
:class="{ active: currentTab === name }" :class="{ active: currentTab === name }"
@click="currentTab = name"
> >
{{ $tc(`globals.listTabs.${name}`, 2) }} {{ $tc(`globals.listTabs.${name}`, 2) }}
</BaseTab> </BaseTab>
@ -31,7 +31,6 @@
<th <th
v-for="data in head" v-for="data in head"
:key="data.title" :key="data.title"
@click="data.sortKey ? sortBy(data.sortKey) : null"
:style="{ width: data.width ? data.width : 'auto' }" :style="{ width: data.width ? data.width : 'auto' }"
class="uppercase-first-letter" class="uppercase-first-letter"
:class="{ :class="{
@ -40,6 +39,7 @@
sortable: data.sortKey, sortable: data.sortKey,
clickable: data.sortKey clickable: data.sortKey
}" }"
@click="data.sortKey ? sortBy(data.sortKey) : null"
> >
<!-- Need to change this behaviour for translations --> <!-- Need to change this behaviour for translations -->
{{ data.title }} {{ data.title }}
@ -74,9 +74,9 @@
<td class="w-32 text-center xl:w-40">{{ release.releaseDate }}</td> <td class="w-32 text-center xl:w-40">{{ release.releaseDate }}</td>
<td class="w-20 text-center xl:w-32">{{ release.releaseTracksNumber }}</td> <td class="w-20 text-center xl:w-32">{{ release.releaseTracksNumber }}</td>
<td <td
@click.stop="sendAddToQueue(release.releaseLink)"
:data-cm-link="release.releaseLink" :data-cm-link="release.releaseLink"
class="w-8 cursor-pointer" class="w-8 cursor-pointer"
@click.stop="sendAddToQueue(release.releaseLink)"
> >
<i class="material-icons hover:text-primary" :title="$t('globals.download_hint')">file_download</i> <i class="material-icons hover:text-primary" :title="$t('globals.download_hint')">file_download</i>
</td> </td>

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<h1 class="mb-8 text-5xl">{{ $t('charts.title') }} {{ country ? (`- ${country}`) : '' }}</h1> <h1 class="mb-8 text-5xl">{{ $t('charts.title') }} {{ country ? `- ${country}` : '' }}</h1>
<div v-if="country === ''"> <div v-if="country === ''">
<div class="release-grid"> <div class="release-grid">
@ -14,7 +14,7 @@
role="button" role="button"
@click="getTrackList" @click="getTrackList"
> >
<img :src="release.picture_medium" class="w-full rounded coverart" :alt="release.title"/> <img :src="release.picture_medium" class="w-full rounded coverart" :alt="release.title" />
</div> </div>
</div> </div>
</div> </div>
@ -26,9 +26,9 @@
</button> </button>
<table class="table table--charts"> <table class="table table--charts">
<tbody> <tbody>
<tr v-for="track, pos in chart" class="track_row"> <tr v-for="(track, pos) in chart" class="track_row">
<td :class="{ first: pos === 0 }" class="p-3 text-center cursor-default"> <td :class="{ first: pos === 0 }" class="p-3 text-center cursor-default">
{{ pos+1 }} {{ pos + 1 }}
</td> </td>
<td class="table__icon table__icon--big"> <td class="table__icon table__icon--big">
<span <span
@ -107,13 +107,22 @@ export default {
}, },
computed: { computed: {
worldwideRelease() { worldwideRelease() {
let worldwideRelease = this.countries.filter(country => { const worldwideRelease = this.countries.filter(country => {
return country.title === 'Worldwide' return country.title === 'Worldwide'
}) })
return worldwideRelease[0] return worldwideRelease[0]
} }
}, },
watch: {
id(newId) {
const isActualChart = newId !== 0
if (isActualChart) {
getChartTracks(newId).then(response => this.setTracklist(response.data))
}
}
},
async created() { async created() {
// socket.on('setChartTracks', this.setTracklist) // socket.on('setChartTracks', this.setTracklist)
// this.$on('hook:destroyed', () => { // this.$on('hook:destroyed', () => {
@ -180,15 +189,6 @@ export default {
localStorage.setItem('chart', this.country) localStorage.setItem('chart', this.country)
} }
} }
},
watch: {
id(newId) {
const isActualChart = newId !== 0
if (isActualChart) {
getChartTracks(newId).then(response => this.setTracklist(response.data))
}
}
} }
} }
</script> </script>

View File

@ -35,5 +35,4 @@ export default {
} }
</script> </script>
<style> <style></style>
</style>

View File

@ -223,7 +223,7 @@ export default defineComponent({
}, },
computed: { computed: {
activeTabEmpty() { activeTabEmpty() {
let toCheck = this.getActiveRelease() const toCheck = this.getActiveRelease()
return toCheck?.length === 0 return toCheck?.length === 0
} }
@ -233,10 +233,10 @@ export default defineComponent({
convertDuration, convertDuration,
downloadAllOfType() { downloadAllOfType() {
try { try {
let toDownload = this.getActiveRelease() const toDownload = this.getActiveRelease()
if (this.activeTab === 'track') { if (this.activeTab === 'track') {
let lovedTracks = this.getLovedTracksPlaylist() const lovedTracks = this.getLovedTracksPlaylist()
sendAddToQueue(lovedTracks.link) sendAddToQueue(lovedTracks.link)
} else { } else {
@ -274,13 +274,13 @@ export default defineComponent({
return toDownload return toDownload
}, },
getTabLength(tab = this.activeTab) { getTabLength(tab = this.activeTab) {
let total = this[`${tab}s`]?.length const total = this[`${tab}s`]?.length
// TODO: Add Spotify playlists to downlaod queue as well // TODO: Add Spotify playlists to downlaod queue as well
//if (tab === "playlist") total += this.spotifyPlaylists.length // if (tab === "playlist") total += this.spotifyPlaylists.length
return total || 0 return total || 0
}, },
getLovedTracksPlaylist() { getLovedTracksPlaylist() {
let lovedTracks = this.playlists.filter(playlist => { const lovedTracks = this.playlists.filter(playlist => {
return playlist.is_loved_track return playlist.is_loved_track
}) })

View File

@ -2,7 +2,7 @@
<div id="home_tab"> <div id="home_tab">
<h1 class="mb-8 text-5xl">{{ $t('globals.welcome') }}</h1> <h1 class="mb-8 text-5xl">{{ $t('globals.welcome') }}</h1>
<section class="py-6 border-0 border-t border-solid border-grayscale-500" ref="notLogged" v-if="!isLoggedIn"> <section v-if="!isLoggedIn" ref="notLogged" class="py-6 border-0 border-t border-solid border-grayscale-500">
<p id="home_not_logged_text" class="mb-4">{{ $t('home.needTologin') }}</p> <p id="home_not_logged_text" class="mb-4">{{ $t('home.needTologin') }}</p>
<router-link tag="button" class="btn btn-primary" name="button" :to="{ name: 'Settings' }"> <router-link tag="button" class="btn btn-primary" name="button" :to="{ name: 'Settings' }">
{{ $t('home.openSettings') }} {{ $t('home.openSettings') }}
@ -13,13 +13,13 @@
<h2 class="mb-6 text-3xl">{{ $t('home.sections.popularPlaylists') }}</h2> <h2 class="mb-6 text-3xl">{{ $t('home.sections.popularPlaylists') }}</h2>
<div class="release-grid"> <div class="release-grid">
<router-link <router-link
tag="div"
v-for="release in playlists" v-for="release in playlists"
:key="release.id" :key="release.id"
tag="div"
class="release clickable" class="release clickable"
:to="{ name: 'Playlist', params: { id: release.id } }" :to="{ name: 'Playlist', params: { id: release.id } }"
@keyup.enter.native="$router.push({ name: 'Playlist', params: { id: release.id } })"
tabindex="0" tabindex="0"
@keyup.enter.native="$router.push({ name: 'Playlist', params: { id: release.id } })"
> >
<CoverContainer is-rounded :cover="release.picture_medium" :link="release.link" @click.stop="addToQueue" /> <CoverContainer is-rounded :cover="release.picture_medium" :link="release.link" @click.stop="addToQueue" />
<p class="primary-text">{{ release.title }}</p> <p class="primary-text">{{ release.title }}</p>
@ -39,14 +39,14 @@
<h2 class="mb-6 text-3xl">{{ $t('home.sections.popularAlbums') }}</h2> <h2 class="mb-6 text-3xl">{{ $t('home.sections.popularAlbums') }}</h2>
<div class="release-grid"> <div class="release-grid">
<router-link <router-link
tag="div"
v-for="release in albums" v-for="release in albums"
:key="release.id" :key="release.id"
tag="div"
class="release clickable" class="release clickable"
:to="{ name: 'Album', params: { id: release.id } }" :to="{ name: 'Album', params: { id: release.id } }"
@keyup.enter.native="$router.push({ name: 'Album', params: { id: release.id } })"
:data-id="release.id" :data-id="release.id"
tabindex="0" tabindex="0"
@keyup.enter.native="$router.push({ name: 'Album', params: { id: release.id } })"
> >
<CoverContainer is-rounded :cover="release.cover_medium" :link="release.link" @click.stop="addToQueue" /> <CoverContainer is-rounded :cover="release.cover_medium" :link="release.link" @click.stop="addToQueue" />
<p class="primary-text">{{ release.title }}</p> <p class="primary-text">{{ release.title }}</p>
@ -100,5 +100,4 @@ export default {
} }
</script> </script>
<style> <style></style>
</style>

View File

@ -2,9 +2,9 @@
<div> <div>
<h1 class="mb-8 text-5xl">{{ $t('settings.login.arl.question') }}</h1> <h1 class="mb-8 text-5xl">{{ $t('settings.login.arl.question') }}</h1>
<p class="mb-2 text-base"> <p class="mb-2 text-base">
Deezer keeps track of login session by using a cookie called ARL.<br> Deezer keeps track of login session by using a cookie called ARL.<br />
deemix uses that cookie to get the metadata that it needs to download the tracks from Deezer.<br> deemix uses that cookie to get the metadata that it needs to download the tracks from Deezer.<br />
ARLs last for 3 months, after that Deezer asks you to log in again. The same method is used in deemix<br> ARLs last for 3 months, after that Deezer asks you to log in again. The same method is used in deemix<br />
Following one of the guides below you can get your own account ARL. Following one of the guides below you can get your own account ARL.
</p> </p>
@ -26,7 +26,7 @@
<li>Go under the Application tab (if you don't see it click the double arrow)</li> <li>Go under the Application tab (if you don't see it click the double arrow)</li>
<li>Open the cookie dropdown</li> <li>Open the cookie dropdown</li>
<li>Select www.deezer.com</li> <li>Select www.deezer.com</li>
<li>Find the `arl` cookie (It should be 192 chars long) </li> <li>Find the `arl` cookie (It should be 192 chars long)</li>
<li>That's your ARL, now you can use it in the app</li> <li>That's your ARL, now you can use it in the app</li>
</ul> </ul>

View File

@ -2,30 +2,39 @@
<div> <div>
<h1 class="mb-8 text-5xl">{{ $t('settings.spotify.question') }}</h1> <h1 class="mb-8 text-5xl">{{ $t('settings.spotify.question') }}</h1>
<p class="mb-2 text-base"> <p class="mb-2 text-base">
"Spotify Features" is a set of features that lets you convert Spotify tracks and albums links into Deezer ones. "Spotify Features" is a set of features that lets you convert Spotify tracks and albums links into Deezer ones. If
If you provide a Spotify Playlist link the app will autmatically convert all the links of the tracks inside it into deezer tracks. you provide a Spotify Playlist link the app will autmatically convert all the links of the tracks inside it into
Enabling this set of features will let you see your public Spotify playlists in the favorites tab as well. deezer tracks. Enabling this set of features will let you see your public Spotify playlists in the favorites tab
as well.
</p> </p>
<p class="mb-2 text-base">For security reasons you will need to provide your own Client ID and Secret</p> <p class="mb-2 text-base">For security reasons you will need to provide your own Client ID and Secret</p>
<h2 class="mt-6 text-3xl">How do I get my Client ID and Secret?</h2> <h2 class="mt-6 text-3xl">How do I get my Client ID and Secret?</h2>
<p class="mb-2 text-base">Connect to <a href="https://developer.spotify.com/dashboard" target="_blank">Spotify for Developers's Dashboard</a> and login with your Spotify account.</p>
<p class="mb-2 text-base"> <p class="mb-2 text-base">
Click on "Create an App".<br> Connect to
<img src="https://i.imgur.com/YFz7rHj.png" alt="Create an App button on Spotify for Developers's Dashboard"> <a href="https://developer.spotify.com/dashboard" target="_blank">Spotify for Developers's Dashboard</a> and login
with your Spotify account.
</p> </p>
<p class="mb-2 text-base"> <p class="mb-2 text-base">
Fill out the "App name" and "App description" fields and check both checkboxes. Then click on the "Create" button.<br> Click on "Create an App".<br />
<img src="https://i.imgur.com/A9cvDkK.png" alt="Create an app form"> <img src="https://i.imgur.com/YFz7rHj.png" alt="Create an App button on Spotify for Developers's Dashboard" />
</p> </p>
<p class="mb-2 text-base"> <p class="mb-2 text-base">
Now you can see the Client ID. If you click on "Show Client Secret" the client secret will be revealed.<br> Fill out the "App name" and "App description" fields and check both checkboxes. Then click on the "Create"
<img src="https://i.imgur.com/foEfIhO.png" alt="Screen of client ID and Secret"> button.<br />
<img src="https://i.imgur.com/A9cvDkK.png" alt="Create an app form" />
</p>
<p class="mb-2 text-base">
Now you can see the Client ID. If you click on "Show Client Secret" the client secret will be revealed.<br />
<img src="https://i.imgur.com/foEfIhO.png" alt="Screen of client ID and Secret" />
</p> </p>
<p class="mb-2 text-base">Now you can copy-paste those results in the appropriate fields in the settings.</p> <p class="mb-2 text-base">Now you can copy-paste those results in the appropriate fields in the settings.</p>
<h2 class="mt-6 text-3xl">How do I get my Spotify Username?</h2> <h2 class="mt-6 text-3xl">How do I get my Spotify Username?</h2>
<p class="mb-2 text-base">You can get your Spotify Username from the <a href="https://www.spotify.com/it/account/overview/" target="_blank">Overview page on Spotify's Website</a>.</p> <p class="mb-2 text-base">
You can get your Spotify Username from the
<a href="https://www.spotify.com/it/account/overview/" target="_blank">Overview page on Spotify's Website</a>.
</p>
</div> </div>
</template> </template>
@ -33,5 +42,4 @@
export default {} export default {}
</script> </script>
<style> <style></style>
</style>

View File

@ -65,10 +65,10 @@
<div <div
role="button" role="button"
aria-label="download" aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue"
:data-link="link" :data-link="link"
class="grid w-16 h-16 ml-auto rounded-full cursor-pointer bg-primary text-grayscale-870 place-items-center" class="grid w-16 h-16 ml-auto rounded-full cursor-pointer bg-primary text-grayscale-870 place-items-center"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue"
> >
<i class="text-4xl material-icons" :title="$t('globals.download_hint')">get_app</i> <i class="text-4xl material-icons" :title="$t('globals.download_hint')">get_app</i>
</div> </div>
@ -152,6 +152,11 @@ export default {
countries: [] countries: []
} }
}, },
mounted() {
socket.on('analyze_track', this.showTrack)
socket.on('analyze_album', this.showAlbum)
socket.on('analyze_notSupported', this.notSupported)
},
methods: { methods: {
convertDuration, convertDuration,
reset() { reset() {
@ -174,15 +179,15 @@ export default {
id id
} = data } = data
this.title = title + (title_version && title.indexOf(title_version) == -1 ? ' ' + title_version : '') this.title = title + (title_version && !title.includes(title_version) ? ' ' + title_version : '')
this.image = cover_xl this.image = cover_xl
this.type = 'track' this.type = 'track'
this.link = link this.link = link
this.id = id this.id = id
available_countries.forEach(cc => { available_countries.forEach(cc => {
let temp = [] const temp = []
let chars = [...cc].map(c => c.charCodeAt() + 127397) const chars = [...cc].map(c => c.charCodeAt() + 127397)
temp.push(String.fromCodePoint(...chars)) temp.push(String.fromCodePoint(...chars))
temp.push(COUNTRIES[cc]) temp.push(COUNTRIES[cc])
this.countries.push(temp) this.countries.push(temp)
@ -207,14 +212,8 @@ export default {
addToQueue(e) { addToQueue(e) {
sendAddToQueue(e.currentTarget.dataset.link) sendAddToQueue(e.currentTarget.dataset.link)
} }
},
mounted() {
socket.on('analyze_track', this.showTrack)
socket.on('analyze_album', this.showAlbum)
socket.on('analyze_notSupported', this.notSupported)
} }
} }
</script> </script>
<style> <style></style>
</style>

View File

@ -12,8 +12,8 @@
<BaseTab <BaseTab
v-for="tab in tabs" v-for="tab in tabs"
:key="tab.name" :key="tab.name"
@click="changeSearchTab(tab.searchType)"
:class="{ active: currentTab.name === tab.name }" :class="{ active: currentTab.name === tab.name }"
@click="changeSearchTab(tab.searchType)"
> >
{{ tab.name }} {{ tab.name }}
</BaseTab> </BaseTab>
@ -22,7 +22,7 @@
<keep-alive> <keep-alive>
<component <component
:is="currentTab.component" :is="currentTab.component"
:viewInfo="getViewInfo()" :view-info="getViewInfo()"
want-headers want-headers
@add-to-queue="addToQueue" @add-to-queue="addToQueue"
@change-search-tab="changeSearchTab" @change-search-tab="changeSearchTab"
@ -245,6 +245,22 @@ export default defineComponent({
return tabsLoaded return tabsLoaded
} }
}, },
watch: {
performScrolledSearch(needToSearch) {
if (!needToSearch) return
this.scrolledSearch(needToSearch)
},
currentTab(newTab, old) {
if (this.isTabLoaded(newTab)) return
this.performSearch({
term: this.results.query,
type: newTab.searchType,
start: this.results[`${newTab.searchType}Tab`].next
})
}
},
methods: { methods: {
numberWithDots, numberWithDots,
convertDuration, convertDuration,
@ -289,29 +305,10 @@ export default defineComponent({
} }
}, },
isTabLoaded(tab) { isTabLoaded(tab) {
return this.loadedTabs.indexOf(tab.searchType) !== -1 || tab.searchType === 'all' return this.loadedTabs.includes(tab.searchType) || tab.searchType === 'all'
}
},
watch: {
performScrolledSearch(needToSearch) {
if (!needToSearch) return
this.scrolledSearch(needToSearch)
},
currentTab(newTab, old) {
if (this.isTabLoaded(newTab)) return
this.performSearch({
term: this.results.query,
type: newTab.searchType,
start: this.results[`${newTab.searchType}Tab`].next
})
} }
} }
}) })
</script> </script>
<style> <style></style>
</style>

View File

@ -61,16 +61,18 @@
</div> </div>
<div class="settings-group"> <div class="settings-group">
<h3 class="settings-group__header"><i class="material-icons">person</i>{{ $t('settings.loginWithCredentials.title') }}</h3> <h3 class="settings-group__header">
<i class="material-icons">person</i>{{ $t('settings.loginWithCredentials.title') }}
</h3>
<form class="my-5 space-y-5" @submit.prevent="loginWithCredentials" ref="loginWithCredentialsForm"> <form ref="loginWithCredentialsForm" class="my-5 space-y-5" @submit.prevent="loginWithCredentials">
<label> <label>
<span>Username</span> <span>Username</span>
<input type="text" name="username"> <input type="text" name="username" />
</label> </label>
<label> <label>
<span>Password</span> <span>Password</span>
<input type="password" name="password"> <input type="password" name="password" />
</label> </label>
<button class="btn btn-primary" type="submit">{{ $t('settings.loginWithCredentials.login') }}</button> <button class="btn btn-primary" type="submit">{{ $t('settings.loginWithCredentials.login') }}</button>
@ -876,14 +878,14 @@ export default {
this.initSettings(settingsData, spotifyCredentials) this.initSettings(settingsData, spotifyCredentials)
// TODO Move in store // TODO Move in store
let storedAccountNum = localStorage.getItem('accountNum') const storedAccountNum = localStorage.getItem('accountNum')
if (storedAccountNum) { if (storedAccountNum) {
this.accountNum = storedAccountNum this.accountNum = storedAccountNum
} }
// TODO Move in store // TODO Move in store
let spotifyUser = localStorage.getItem('spotifyUser') const spotifyUser = localStorage.getItem('spotifyUser')
if (spotifyUser) { if (spotifyUser) {
this.lastUser = spotifyUser this.lastUser = spotifyUser
@ -924,7 +926,7 @@ export default {
this.spotifyUser = (' ' + this.lastUser).slice(1) this.spotifyUser = (' ' + this.lastUser).slice(1)
}, },
copyARLtoClipboard() { copyARLtoClipboard() {
let copyText = this.$refs.loginInput const copyText = this.$refs.loginInput
copyText.setAttribute('type', 'text') copyText.setAttribute('type', 'text')
copyText.select() copyText.select()
@ -978,7 +980,7 @@ export default {
// const res = await fetchData('login', { arl, force: true, child: this.accountNum }) // const res = await fetchData('login', { arl, force: true, child: this.accountNum })
}, },
async login() { async login() {
let newArl = this.$refs.loginInput.value.trim() const newArl = this.$refs.loginInput.value.trim()
if (newArl && newArl !== this.arl) { if (newArl && newArl !== this.arl) {
const res = await fetchData('login-arl', { arl: newArl, force: true, child: this.accountNum }, 'POST') const res = await fetchData('login-arl', { arl: newArl, force: true, child: this.accountNum }, 'POST')
@ -1020,7 +1022,7 @@ export default {
toast(this.$t('settings.toasts.init'), 'settings') toast(this.$t('settings.toasts.init'), 'settings')
}, },
updateSettings(data) { updateSettings(data) {
const {settings: newSettings, spotifySettings: newCredentials} = data const { settings: newSettings, spotifySettings: newCredentials } = data
this.loadSettings(newSettings) this.loadSettings(newSettings)
this.loadCredentials(newCredentials) this.loadCredentials(newCredentials)

View File

@ -41,7 +41,6 @@
<td class="table__cell--x-small table__cell--center"> <td class="table__cell--x-small table__cell--center">
<div class="table__cell-content table__cell-content--vertical-center"> <div class="table__cell-content table__cell-content--vertical-center">
<i <i
v-on="{ click: track.preview ? playPausePreview : false }"
:class="{ :class="{
preview_playlist_controls: track.preview, preview_playlist_controls: track.preview,
'cursor-pointer': track.preview, 'cursor-pointer': track.preview,
@ -50,6 +49,7 @@
:data-preview="track.preview" :data-preview="track.preview"
:title="$t('globals.play_hint')" :title="$t('globals.play_hint')"
class="material-icons" class="material-icons"
v-on="{ click: track.preview ? playPausePreview : false }"
> >
play_arrow play_arrow
</i> </i>

View File

@ -7,8 +7,8 @@
<h1>{{ $t('search.noResultsAlbum') }}</h1> <h1>{{ $t('search.noResultsAlbum') }}</h1>
</div> </div>
<div class="release-grid" v-else> <div v-else class="release-grid">
<div class="w-40 release" v-for="release in viewInfo.data.slice(0, itemsToShow)" :key="release.albumID"> <div v-for="release in viewInfo.data.slice(0, itemsToShow)" :key="release.albumID" class="w-40 release">
<router-link tag="div" class="cursor-pointer" :to="{ name: 'Album', params: { id: release.albumID } }"> <router-link tag="div" class="cursor-pointer" :to="{ name: 'Album', params: { id: release.albumID } }">
<CoverContainer <CoverContainer
is-rounded is-rounded
@ -53,9 +53,9 @@ export default {
}, },
props: { props: {
viewInfo: { viewInfo: {
validator: function (value) { validator(value) {
let isNull = Object.is(value, null) const isNull = Object.is(value, null)
let isObject = Object.prototype.toString.call(value) === '[object Object]' const isObject = Object.prototype.toString.call(value) === '[object Object]'
return isNull || isObject return isNull || isObject
}, },

View File

@ -12,13 +12,13 @@
> >
<template v-if="checkSectionResults(section)"> <template v-if="checkSectionResults(section)">
<h2 <h2
@click="$emit('change-search-tab', section)"
class="mb-6 capitalize" class="mb-6 capitalize"
:class="{ :class="{
'text-4xl text-center': section === 'TOP_RESULT', 'text-4xl text-center': section === 'TOP_RESULT',
'inline-block cursor-pointer text-3xl hover:text-primary transition-colors duration-200 ease-in-out': 'inline-block cursor-pointer text-3xl hover:text-primary transition-colors duration-200 ease-in-out':
section !== 'TOP_RESULT' section !== 'TOP_RESULT'
}" }"
@click="$emit('change-search-tab', section)"
> >
{{ $tc(`globals.listTabs.${section.toLowerCase()}`, 2) }} {{ $tc(`globals.listTabs.${section.toLowerCase()}`, 2) }}
</h2> </h2>
@ -31,29 +31,29 @@
<ResultsTracks <ResultsTracks
v-else-if="section === 'TRACK'" v-else-if="section === 'TRACK'"
:viewInfo="standardizeData(viewInfo.TRACK, formatSingleTrack)" :view-info="standardizeData(viewInfo.TRACK, formatSingleTrack)"
:itemsToShow="6" :items-to-show="6"
@add-to-queue="$emit('add-to-queue', $event)" @add-to-queue="$emit('add-to-queue', $event)"
/> />
<ResultsAlbums <ResultsAlbums
v-else-if="section == 'ALBUM'" v-else-if="section == 'ALBUM'"
:viewInfo="standardizeData(viewInfo.ALBUM, formatAlbums)" :view-info="standardizeData(viewInfo.ALBUM, formatAlbums)"
:itemsToShow="6" :items-to-show="6"
@add-to-queue="$emit('add-to-queue', $event)" @add-to-queue="$emit('add-to-queue', $event)"
/> />
<ResultsPlaylists <ResultsPlaylists
v-else-if="section == 'PLAYLIST'" v-else-if="section == 'PLAYLIST'"
:viewInfo="standardizeData(viewInfo.PLAYLIST, formatPlaylist)" :view-info="standardizeData(viewInfo.PLAYLIST, formatPlaylist)"
:itemsToShow="6" :items-to-show="6"
@add-to-queue="$emit('add-to-queue', $event)" @add-to-queue="$emit('add-to-queue', $event)"
/> />
<ResultsArtists <ResultsArtists
v-else-if="section === 'ARTIST'" v-else-if="section === 'ARTIST'"
:viewInfo="standardizeData(viewInfo.ARTIST, formatArtist)" :view-info="standardizeData(viewInfo.ARTIST, formatArtist)"
:itemsToShow="6" :items-to-show="6"
@add-to-queue="$emit('add-to-queue', $event)" @add-to-queue="$emit('add-to-queue', $event)"
/> />
</template> </template>
@ -90,13 +90,13 @@ export default {
}, },
computed: { computed: {
thereAreResults() { thereAreResults() {
let areInfosLoaded = !!this.viewInfo const areInfosLoaded = !!this.viewInfo
if (!areInfosLoaded) { if (!areInfosLoaded) {
return false return false
} }
let noResultsPresent = this.viewInfo.ORDER.every(section => const noResultsPresent = this.viewInfo.ORDER.every(section =>
section === 'TOP_RESULT' ? this.viewInfo[section].length === 0 : this.viewInfo[section].data.length === 0 section === 'TOP_RESULT' ? this.viewInfo[section].length === 0 : this.viewInfo[section].data.length === 0
) )

View File

@ -8,7 +8,7 @@
</div> </div>
<div v-else class="release-grid"> <div v-else class="release-grid">
<div class="w-40 release" v-for="release in viewInfo.data.slice(0, itemsToShow)" :key="release.artistID"> <div v-for="release in viewInfo.data.slice(0, itemsToShow)" :key="release.artistID" class="w-40 release">
<router-link tag="div" class="cursor-pointer" :to="{ name: 'Artist', params: { id: release.artistID } }"> <router-link tag="div" class="cursor-pointer" :to="{ name: 'Artist', params: { id: release.artistID } }">
<CoverContainer <CoverContainer
is-circle is-circle
@ -41,9 +41,9 @@ export default {
}, },
props: { props: {
viewInfo: { viewInfo: {
validator: function (value) { validator(value) {
let isNull = Object.is(value, null) const isNull = Object.is(value, null)
let isObject = Object.prototype.toString.call(value) === '[object Object]' const isObject = Object.prototype.toString.call(value) === '[object Object]'
return isNull || isObject return isNull || isObject
}, },

View File

@ -6,8 +6,8 @@
<div v-if="viewInfo.data.length === 0"> <div v-if="viewInfo.data.length === 0">
<h1>{{ $t('search.noResultsPlaylist') }}</h1> <h1>{{ $t('search.noResultsPlaylist') }}</h1>
</div> </div>
<div class="release-grid" v-else> <div v-else class="release-grid">
<div class="w-40 release" v-for="playlist in viewInfo.data.slice(0, itemsToShow)" :key="playlist.playlistID"> <div v-for="playlist in viewInfo.data.slice(0, itemsToShow)" :key="playlist.playlistID" class="w-40 release">
<router-link tag="div" class="cursor-pointer" :to="{ name: 'Playlist', params: { id: playlist.playlistID } }"> <router-link tag="div" class="cursor-pointer" :to="{ name: 'Playlist', params: { id: playlist.playlistID } }">
<CoverContainer <CoverContainer
is-rounded is-rounded
@ -46,9 +46,9 @@ export default {
}, },
props: { props: {
viewInfo: { viewInfo: {
validator: function (value) { validator(value) {
let isNull = Object.is(value, null) const isNull = Object.is(value, null)
let isObject = Object.prototype.toString.call(value) === '[object Object]' const isObject = Object.prototype.toString.call(value) === '[object Object]'
return isNull || isObject return isNull || isObject
}, },

View File

@ -24,9 +24,9 @@
<tr v-for="track in viewInfo.data.slice(0, itemsToShow)" :key="track.trackLink"> <tr v-for="track in viewInfo.data.slice(0, itemsToShow)" :key="track.trackLink">
<td class="table__icon table__icon--big"> <td class="table__icon table__icon--big">
<span <span
@click="playPausePreview($event)"
class="relative inline-block rounded cursor-pointer" class="relative inline-block rounded cursor-pointer"
:data-preview="track.trackPreview" :data-preview="track.trackPreview"
@click="playPausePreview($event)"
> >
<PreviewControls v-if="track.trackPreview" /> <PreviewControls v-if="track.trackPreview" />
@ -67,9 +67,9 @@
<td <td
class="cursor-pointer table__cell--center group" class="cursor-pointer table__cell--center group"
@click.stop="$emit('add-to-queue', $event)"
:data-link="track.trackLink" :data-link="track.trackLink"
aria-label="download" aria-label="download"
@click.stop="$emit('add-to-queue', $event)"
> >
<i <i
class="transition-colors duration-150 ease-in-out material-icons group-hover:text-primary" class="transition-colors duration-150 ease-in-out material-icons group-hover:text-primary"
@ -101,9 +101,9 @@ export default {
}, },
props: { props: {
viewInfo: { viewInfo: {
validator: function (value) { validator(value) {
let isNull = Object.is(value, null) const isNull = Object.is(value, null)
let isObject = Object.prototype.toString.call(value) === '[object Object]' const isObject = Object.prototype.toString.call(value) === '[object Object]'
return isNull || isObject return isNull || isObject
}, },

View File

@ -28,7 +28,6 @@
</div> </div>
</template> </template>
<script> <script>
import { upperCaseFirstLowerCaseRest } from '@/utils/texts' import { upperCaseFirstLowerCaseRest } from '@/utils/texts'
import CoverContainer from '@components/globals/CoverContainer.vue' import CoverContainer from '@components/globals/CoverContainer.vue'
@ -37,9 +36,6 @@ export default {
components: { components: {
CoverContainer CoverContainer
}, },
methods: {
upperCaseFirstLowerCaseRest
},
computed: { computed: {
fansNumber() { fansNumber() {
let number let number
@ -56,6 +52,9 @@ export default {
' - ' + ' - ' +
this.$tc('globals.listTabs.trackN', this.$attrs.info.nb_song) this.$tc('globals.listTabs.trackN', this.$attrs.info.nb_song)
} }
},
methods: {
upperCaseFirstLowerCaseRest
} }
} }
</script> </script>

View File

@ -1,5 +1,5 @@
<template> <template>
<BaseAccordion style="--arrow-v-align: baseline; margin-bottom: 3rem;"> <BaseAccordion style="--arrow-v-align: baseline; margin-bottom: 3rem">
<template #title> <template #title>
<slot name="title"></slot> <slot name="title"></slot>
</template> </template>

View File

@ -10,7 +10,7 @@ export function formatArtistData(artistData) {
} }
function formatArtistReleases(artistReleases) { function formatArtistReleases(artistReleases) {
let formattedReleases = {} const formattedReleases = {}
for (const releaseType in artistReleases) { for (const releaseType in artistReleases) {
if (artistReleases.hasOwnProperty(releaseType)) { if (artistReleases.hasOwnProperty(releaseType)) {

View File

@ -54,7 +54,7 @@ export function formatAlbums(album) {
'EXPLICIT_ALBUM_CONTENT.EXPLICIT_LYRICS_STATUS' 'EXPLICIT_ALBUM_CONTENT.EXPLICIT_LYRICS_STATUS'
) )
if ('number' === typeof isAlbumExplicit) { if (typeof isAlbumExplicit === 'number') {
isAlbumExplicit = isAlbumExplicit === 1 isAlbumExplicit = isAlbumExplicit === 1
} }
@ -95,9 +95,7 @@ export function formatPlaylist(playlist) {
playlistTitle: getPropertyWithFallback(playlist, 'title', 'TITLE'), playlistTitle: getPropertyWithFallback(playlist, 'title', 'TITLE'),
playlistPictureMedium: playlistPictureMedium:
getPropertyWithFallback(playlist, 'picture_medium') || getPropertyWithFallback(playlist, 'picture_medium') ||
`https://e-cdns-images.dzcdn.net/images/${playlist.PICTURE_TYPE}/${ `https://e-cdns-images.dzcdn.net/images/${playlist.PICTURE_TYPE}/${playlist.PLAYLIST_PICTURE}/156x156-000000-80-0-0.jpg`,
playlist.PLAYLIST_PICTURE
}/156x156-000000-80-0-0.jpg`,
playlistLink: getPropertyWithFallback(playlist, 'link') || `https://deezer.com/playlist/${playlist.PLAYLIST_ID}`, playlistLink: getPropertyWithFallback(playlist, 'link') || `https://deezer.com/playlist/${playlist.PLAYLIST_ID}`,
playlistTracksNumber: getPropertyWithFallback(playlist, 'nb_tracks', 'NB_SONG'), playlistTracksNumber: getPropertyWithFallback(playlist, 'nb_tracks', 'NB_SONG'),
@ -107,7 +105,7 @@ export function formatPlaylist(playlist) {
} }
export function formatTitle(track) { export function formatTitle(track) {
const hasTitleVersion = track.trackTitleVersion && track.trackTitle.indexOf(track.trackTitleVersion) === -1 const hasTitleVersion = track.trackTitleVersion && !track.trackTitle.includes(track.trackTitleVersion)
return `${track.trackTitle}${hasTitleVersion ? ` ${track.trackTitleVersion}` : ''}` return `${track.trackTitle}${hasTitleVersion ? ` ${track.trackTitleVersion}` : ''}`
} }

View File

@ -4,12 +4,12 @@ let settingsData = {}
let defaultSettingsData = {} let defaultSettingsData = {}
let spotifyCredentials = {} let spotifyCredentials = {}
let cached = false const cached = false
export async function getSettingsData() { export async function getSettingsData() {
if (!cached) { if (!cached) {
let data = await fetchData('getSettings') const data = await fetchData('getSettings')
let { settings, defaultSettings, spotifySettings } = data const { settings, defaultSettings, spotifySettings } = data
// cached = true // cached = true
settingsData = settings settingsData = settings
defaultSettingsData = defaultSettings defaultSettingsData = defaultSettings
@ -36,12 +36,12 @@ export function getInitialPreviewVolume() {
* @returns {boolean} * @returns {boolean}
*/ */
export function checkInitialSlimDownloads() { export function checkInitialSlimDownloads() {
return 'true' === localStorage.getItem('slimDownloads') return localStorage.getItem('slimDownloads') === 'true'
} }
/** /**
* @returns {boolean} * @returns {boolean}
*/ */
export function checkInitialSlimSidebar() { export function checkInitialSlimSidebar() {
return 'true' === localStorage.getItem('slimSidebar') return localStorage.getItem('slimSidebar') === 'true'
} }

View File

@ -6,7 +6,7 @@ export function standardizeData(rawObj, formatFunc) {
const formattedData = [] const formattedData = []
for (const dataElement of rawData) { for (const dataElement of rawData) {
let formatted = formatFunc(dataElement) const formatted = formatFunc(dataElement)
formattedData.push(formatted) formattedData.push(formatted)
} }

View File

@ -39,11 +39,12 @@ const ar = {
license: 'الرخصة' license: 'الرخصة'
}, },
subtitles: { subtitles: {
bugReports: "هل هناك شيء لا يعمل في ديمكس؟ أخبرنا", bugReports: 'هل هناك شيء لا يعمل في ديمكس؟ أخبرنا',
contributing: 'تريد المساهمة في هذا المشروع؟ يمكنك القيام بذلك بعدة طرق', contributing: 'تريد المساهمة في هذا المشروع؟ يمكنك القيام بذلك بعدة طرق',
donations: 'تريد المساهمة مادياً؟ يمكنك التبرع' donations: 'تريد المساهمة مادياً؟ يمكنك التبرع'
}, },
usesLibrary: 'هذا البرنامج يستخدم مكتبة <strong>ديمكس</strong> والتي يمكنك استخدامها لإنشاء واجهة مستخدم خاصة بك لديمكس.', usesLibrary:
'هذا البرنامج يستخدم مكتبة <strong>ديمكس</strong> والتي يمكنك استخدامها لإنشاء واجهة مستخدم خاصة بك لديمكس.',
thanks: `شكرا لـ <strong>rtonno</strong>, و <strong>uhwot</strong> و <strong>lollilol</strong> لمساعدتي في هذا المشروع و لـ <strong>BasCurtiz</strong> لصنع الايقونة.`, thanks: `شكرا لـ <strong>rtonno</strong>, و <strong>uhwot</strong> و <strong>lollilol</strong> لمساعدتي في هذا المشروع و لـ <strong>BasCurtiz</strong> لصنع الايقونة.`,
officialWebsite: 'الموقع الرسمي', officialWebsite: 'الموقع الرسمي',
officialRepo: 'مستودع المكتبة الرسمي', officialRepo: 'مستودع المكتبة الرسمي',
@ -58,7 +59,7 @@ const ar = {
otherLanguages: `إذا كنت تجيد لغة برمجة أخرى ، يمكنك محاولة تحويل ديمكس إلى لغات برمجة أخرى!`, otherLanguages: `إذا كنت تجيد لغة برمجة أخرى ، يمكنك محاولة تحويل ديمكس إلى لغات برمجة أخرى!`,
understandingCode: `أنت بحاجة إلى مساعدة في فهم الكود؟ فقط اتصل بـ RemixDev على تيليكرام او ريديت.`, understandingCode: `أنت بحاجة إلى مساعدة في فهم الكود؟ فقط اتصل بـ RemixDev على تيليكرام او ريديت.`,
itsFree: `يجب ان تتذكر ان <strong>هذا هو مشروع مجاني</strong> <strong>و عليك دعم الفنانين المفضلين لك قبل ان تدعم مطورين البرنامج</strong>.`, itsFree: `يجب ان تتذكر ان <strong>هذا هو مشروع مجاني</strong> <strong>و عليك دعم الفنانين المفضلين لك قبل ان تدعم مطورين البرنامج</strong>.`,
notObligated: `لا تشعر بالالتزام بالتبرع ، لكني أقدر ذلك على أي حال!`, notObligated: `لا تشعر بالالتزام بالتبرع ، لكني أقدر ذلك على أي حال!`
}, },
charts: { charts: {
title: 'قائمة الجداول', title: 'قائمة الجداول',
@ -71,7 +72,7 @@ const ar = {
invalidURL: 'الرابط غير صحيح', invalidURL: 'الرابط غير صحيح',
unsupportedURL: 'الرابط غير متاح حتى الانً', unsupportedURL: 'الرابط غير متاح حتى الانً',
ISRCnotOnDeezer: 'رمز المقطع غير متوفر في ديزر', ISRCnotOnDeezer: 'رمز المقطع غير متوفر في ديزر',
notYourPrivatePlaylist: "لا يمكنك تحميل قوائم التشغيل الخاصة و المخفية.", notYourPrivatePlaylist: 'لا يمكنك تحميل قوائم التشغيل الخاصة و المخفية.',
spotifyDisabled: 'لم يتم اعداد ميزات سبوتفاي بالطرقة الصحيحة .', spotifyDisabled: 'لم يتم اعداد ميزات سبوتفاي بالطرقة الصحيحة .',
trackNotOnDeezer: 'المقطع لا يوجد في ديزر!', trackNotOnDeezer: 'المقطع لا يوجد في ديزر!',
albumNotOnDeezer: 'الالبوم لا يوجد في ديزر!', albumNotOnDeezer: 'الالبوم لا يوجد في ديزر!',
@ -81,8 +82,8 @@ const ar = {
wrongBitrate: 'لم يتم العثور على المقطع في الدقة المطلوبة.', wrongBitrate: 'لم يتم العثور على المقطع في الدقة المطلوبة.',
wrongBitrateNoAlternative: 'لم يتم العثور على المقطع في الدقة المطلوبة و لا توجد دقة بديلة!', wrongBitrateNoAlternative: 'لم يتم العثور على المقطع في الدقة المطلوبة و لا توجد دقة بديلة!',
no360RA: 'المقطع غير متوفر في Reality Audio 360.', no360RA: 'المقطع غير متوفر في Reality Audio 360.',
notAvailable: "المقطع غير متوفر في سيرفرات ديزر!", notAvailable: 'المقطع غير متوفر في سيرفرات ديزر!',
notAvailableNoAlternative: "المقطع غير متوفر في سيرفرات ديزر و لا يوجد بديل حتى الان!" notAvailableNoAlternative: 'المقطع غير متوفر في سيرفرات ديزر و لا يوجد بديل حتى الان!'
} }
}, },
favorites: { favorites: {
@ -102,8 +103,7 @@ const ar = {
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'يمكنك استخدام هذا القسم للعثور على مزيد من المعلومات حول الرابط الذي تحاول تنزيله.', info: 'يمكنك استخدام هذا القسم للعثور على مزيد من المعلومات حول الرابط الذي تحاول تنزيله.',
useful: useful: ' كمثال هذا مفيد إذا كنت تحاول تنزيل بعض المقاطع الغير المتاحة في بلدك وتريد معرفة مكان توفرها .',
" كمثال هذا مفيد إذا كنت تحاول تنزيل بعض المقاطع الغير المتاحة في بلدك وتريد معرفة مكان توفرها .",
linkNotSupported: 'هذا الرابط غير معتمد حتى الآن', linkNotSupported: 'هذا الرابط غير معتمد حتى الآن',
linkNotSupportedYet: 'يبدو أن هذا الرابط غير معتمد حتى الآن ، حاول تحليل رابط آخر.', linkNotSupportedYet: 'يبدو أن هذا الرابط غير معتمد حتى الآن ، حاول تحليل رابط آخر.',
table: { table: {
@ -123,8 +123,7 @@ const ar = {
}, },
search: { search: {
startSearching: 'ابدأ البحث!', startSearching: 'ابدأ البحث!',
description: description: 'يمكنك البحث عن مقطع ، ألبوم كامل ، فنان ، قائمة تشغيل .... كل شيء! يمكنك أيضًا لصق رابط ديزر',
'يمكنك البحث عن مقطع ، ألبوم كامل ، فنان ، قائمة تشغيل .... كل شيء! يمكنك أيضًا لصق رابط ديزر',
fans: '{n} متابعون', fans: '{n} متابعون',
noResults: 'لا يوجد نتائج', noResults: 'لا يوجد نتائج',
noResultsTrack: 'لم يتم العثور على مقاطع', noResultsTrack: 'لم يتم العثور على مقاطع',
@ -143,7 +142,7 @@ const ar = {
loggingIn: 'جار تسجيل الدخول...', loggingIn: 'جار تسجيل الدخول...',
loggedIn: 'تم تسجيل الدخول', loggedIn: 'تم تسجيل الدخول',
alreadyLogged: 'تم تسجيل الدخول بالفعل', alreadyLogged: 'تم تسجيل الدخول بالفعل',
loginFailed: "تعذر تسجيل الدخول", loginFailed: 'تعذر تسجيل الدخول',
loggedOut: 'تم تسجيل الخروج', loggedOut: 'تم تسجيل الخروج',
cancellingCurrentItem: 'جار الغاء العنصر الحالي.', cancellingCurrentItem: 'جار الغاء العنصر الحالي.',
currentItemCancelled: 'تم الغاء العنصر الحالي.', currentItemCancelled: 'تم الغاء العنصر الحالي.',
@ -208,7 +207,7 @@ const ar = {
overwriteFile: { overwriteFile: {
title: 'هل يمكنني استبدال الملفات?', title: 'هل يمكنني استبدال الملفات?',
y: 'نعم, استبدال الملفات', y: 'نعم, استبدال الملفات',
n: "لا, لا تبدل الملفات", n: 'لا, لا تبدل الملفات',
t: 'استبدل العلامات فقط', t: 'استبدل العلامات فقط',
b: 'لا ، احتفظ بالملفين وأضف رقمًا إلى الملف المكرر' b: 'لا ، احتفظ بالملفين وأضف رقمًا إلى الملف المكرر'
}, },

View File

@ -43,8 +43,10 @@ const de = {
contributing: 'Du möchtest bei dem Projekt helfen? Das kannst du auf verschiedene Arten machen!', contributing: 'Du möchtest bei dem Projekt helfen? Das kannst du auf verschiedene Arten machen!',
donations: 'Du möchtest deemix finanziell unterstützen? Dann lasse eine kleine Spende da!' donations: 'Du möchtest deemix finanziell unterstützen? Dann lasse eine kleine Spende da!'
}, },
usesLibrary: 'Dieses Programm nutzt die <strong>deemix</strong> Bibliothek, die du dazu nutzen kannst deine eigene deemix UI zu erstellen.', usesLibrary:
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> für die Erstellung des Logos.', 'Dieses Programm nutzt die <strong>deemix</strong> Bibliothek, die du dazu nutzen kannst deine eigene deemix UI zu erstellen.',
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> für die Erstellung des Logos.',
upToDate: { upToDate: {
text: 'Bleib auf dem Laufenden mit den Updates indem du dem {newsChannel} auf Telegram folgst.', text: 'Bleib auf dem Laufenden mit den Updates indem du dem {newsChannel} auf Telegram folgst.',
newsChannel: 'News Channel' newsChannel: 'News Channel'
@ -55,27 +57,35 @@ const de = {
officialSubreddit: 'Offizieller Subreddit', officialSubreddit: 'Offizieller Subreddit',
newsChannel: 'News Channel', newsChannel: 'News Channel',
questions: { questions: {
text:'Bei Fragen oder Problemen mit der App, suche als erstes nach einer Lösung im {subreddit}. Wenn du da nichts findest, kannst du einen Beitrag mit deinen Problem auf dem Subreddit verfassen.', text:
'Bei Fragen oder Problemen mit der App, suche als erstes nach einer Lösung im {subreddit}. Wenn du da nichts findest, kannst du einen Beitrag mit deinen Problem auf dem Subreddit verfassen.',
subreddit: 'Subreddit' subreddit: 'Subreddit'
}, },
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.', beforeReporting:
beSure: 'Stelle sicher, dass der Bug auf anderen Computern auch vorhanden ist <strong>MELDEN NICHT</strong> einen Bug, wenn er schon gemeldet worden ist.', '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:
'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, achte darauf.', duplicateReports: 'Doppelte Fehlerberichte werden geschlossen, achte darauf.',
dontOpenIssues: '<strong>ERSTELLE KEINE</strong> Fehlermeldungen um Fragen zu stellen, es gibt einen Subreddit dafür.', dontOpenIssues:
'<strong>ERSTELLE KEINE</strong> Fehlermeldungen um Fragen zu stellen, es gibt einen Subreddit dafür.',
newUI: { newUI: {
text: '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 {repo} zu beheben.', text:
'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 {repo} zu beheben.',
repo: 'deemix Repo' repo: 'deemix Repo'
}, },
acceptFeatures: 'Ich akzeptiere auch Funktionen, aber keine komplexen Dinge, da sie direkt in der App und nicht in der Bibliothek implementiert werden können.', acceptFeatures:
otherLanguages: 'Wenn du eine andere Programmiersprache fließend beherrschst, kannst du versuchen, deemix in andere Programmiersprachen zu portieren!', '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, kannst du versuchen, deemix in andere Programmiersprachen zu portieren!',
understandingCode: 'Du benötigst Hilfe beim verstehen des Codes? Frag einfach RemixDev auf Telegram oder Reddit.', understandingCode: 'Du benötigst Hilfe beim verstehen des Codes? Frag einfach RemixDev auf Telegram oder Reddit.',
contributeWebUI: { contributeWebUI: {
text: 'Wenn du Vue.js (JavaScript) oder HTML und CSS kennst, könntest du etwas zum {webui} beitragen.', text: 'Wenn du Vue.js (JavaScript) oder HTML und CSS kennst, könntest du etwas zum {webui} beitragen.',
webui: 'WebUI' webui: 'WebUI'
}, },
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.', 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 gezwungen zu spenden, danke, dass du deemix verwendest!', notObligated: 'Fühle dich nicht gezwungen zu spenden, danke, dass du deemix verwendest!',
lincensedUnder:{ lincensedUnder: {
text: 'Diese Arbeit ist lizensiert unter der {gpl3}.', text: 'Diese Arbeit ist lizensiert unter der {gpl3}.',
gpl3: 'GNU General Public License 3.0' gpl3: 'GNU General Public License 3.0'
} }
@ -91,7 +101,7 @@ const de = {
invalidURL: 'URL nicht erkannt', invalidURL: 'URL nicht erkannt',
unsupportedURL: 'URL noch nicht unterstützt', unsupportedURL: 'URL noch nicht unterstützt',
ISRCnotOnDeezer: 'Track 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-Funktionen sind nicht richtig eingerichtet', spotifyDisabled: 'Spotify-Funktionen sind nicht richtig eingerichtet',
trackNotOnDeezer: 'Track ist nicht verfügbar auf Deezer!', trackNotOnDeezer: 'Track ist nicht verfügbar auf Deezer!',
albumNotOnDeezer: 'Album auf Deezer nicht gefunden!', albumNotOnDeezer: 'Album auf Deezer nicht gefunden!',
@ -101,8 +111,9 @@ const de = {
wrongBitrate: 'Track mit gewünschter Bitrate nicht gefunden.', wrongBitrate: 'Track mit gewünschter Bitrate nicht gefunden.',
wrongBitrateNoAlternative: 'Track mit gewünschter Bitrate nicht gefunden und keine Alternative gefunden!', wrongBitrateNoAlternative: 'Track mit gewünschter Bitrate nicht gefunden und keine Alternative gefunden!',
no360RA: 'Track ist nicht verfügbar in Reality Audio 360.', no360RA: 'Track ist nicht verfügbar in Reality Audio 360.',
notAvailable: "Track ist noch nicht verfügbar auf den Servern von Deezer!", notAvailable: 'Track ist noch nicht verfügbar auf den Servern von Deezer!',
notAvailableNoAlternative: "Track ist noch nicht verfügbar auf den Servern von Deezer und keine Alternativen gefunden!!" notAvailableNoAlternative:
'Track ist noch nicht verfügbar auf den Servern von Deezer und keine Alternativen gefunden!!'
} }
}, },
favorites: { favorites: {
@ -121,10 +132,13 @@ const de = {
} }
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'Diesen Abschnitt kannst du nutzen, um weitere Informationen über den gewünschten Link zu erhalten, den du herunterladen möchtest.', info:
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.", 'Diesen Abschnitt kannst du nutzen, um weitere Informationen über den gewünschten Link zu erhalten, den du herunterladen möchtest.',
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.',
linkNotSupported: 'Dieser Link wird noch nicht unterstützt', linkNotSupported: 'Dieser Link wird noch nicht unterstützt',
linkNotSupportedYet: 'Es scheint so, als ob dieser Link noch nicht unterstützt wird. Versuche einen anderen Link 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',
@ -142,7 +156,8 @@ const de = {
}, },
search: { search: {
startSearching: 'Suche starten!', startSearching: 'Suche starten!',
description: 'Du kannst einen Titel, ein ganzes Album, einen Künstler, eine Playlist suchen ... alles! Du kannst auch einen Deezer-Link einfügen', description:
'Du kannst einen Titel, ein ganzes Album, einen Künstler, eine Playlist suchen ... alles! Du kannst auch einen Deezer-Link einfügen',
fans: '{n} Fans', fans: '{n} Fans',
noResults: 'Keine Ergebnisse', noResults: 'Keine Ergebnisse',
noResultsTrack: 'Keine Tracks gefunden', noResultsTrack: 'Keine Tracks gefunden',
@ -161,7 +176,7 @@ const de = {
loggingIn: 'Einloggen', loggingIn: 'Einloggen',
loggedIn: 'Eingeloggt', loggedIn: 'Eingeloggt',
alreadyLogged: 'Bereits eingeloggt', alreadyLogged: 'Bereits eingeloggt',
loginFailed: "Login fehlgeschlagen", loginFailed: 'Login fehlgeschlagen',
loggedOut: 'Ausgeloggt', loggedOut: 'Ausgeloggt',
cancellingCurrentItem: 'Aktuelle Auswahl abbrechen.', cancellingCurrentItem: 'Aktuelle Auswahl abbrechen.',
currentItemCancelled: 'Aktuelle Auswahl wurde abgebrochen', currentItemCancelled: 'Aktuelle Auswahl wurde abgebrochen',
@ -228,7 +243,6 @@ const de = {
n: 'Nein überschreibe die Dateien nicht', n: 'Nein überschreibe die Dateien nicht',
t: 'Überschreibe nur die Tags', t: 'Überschreibe nur die Tags',
b: 'Nein, behalte beide Dateien und füge der Kopie eine Nummer hinzu' b: 'Nein, behalte beide Dateien und füge der Kopie eine Nummer hinzu'
}, },
fallbackBitrate: 'Falls gewünschte Bitrate nicht verfügbar, auf niedrigere Bitrate zurückgreifen', fallbackBitrate: 'Falls gewünschte Bitrate nicht verfügbar, auf niedrigere Bitrate zurückgreifen',
fallbackSearch: 'Zur Suche zurückkehren, wenn der Song nicht verfügbar ist', fallbackSearch: 'Zur Suche zurückkehren, wenn der Song nicht verfügbar ist',

View File

@ -58,7 +58,8 @@ const es = {
contributing: '¿Quieres contribuir a este proyecto? ¡Puedes hacerlo de diferentes maneras!', contributing: '¿Quieres contribuir a este proyecto? ¡Puedes hacerlo de diferentes maneras!',
donations: '¿Quiere contribuir monetariamente? ¡Puedes hacer una donación!' donations: '¿Quiere contribuir monetariamente? ¡Puedes hacer una donación!'
}, },
usesLibrary: 'Esta aplicación usa la biblioteca <strong>deemix</strong>, que puedes usar para hacer tu propia interfaz de usuario para deemix.', usesLibrary:
'Esta aplicación usa la biblioteca <strong>deemix</strong>, que puedes usar para hacer tu propia interfaz de usuario para deemix.',
thanks: `Gracias a <strong>rtonno</strong>, <strong>uhwot</strong> y <strong>lollilol</strong> por ayudarme con este proyecto, a <strong>BasCurtiz</strong> por hacer el icono.`, thanks: `Gracias a <strong>rtonno</strong>, <strong>uhwot</strong> y <strong>lollilol</strong> por ayudarme con este proyecto, a <strong>BasCurtiz</strong> por hacer el icono.`,
upToDate: { upToDate: {
text: `Mantente al día con las actualizaciones siguiendo el {newsChannel} en Telegram.`, text: `Mantente al día con las actualizaciones siguiendo el {newsChannel} en Telegram.`,
@ -73,22 +74,27 @@ const es = {
text: `Si tienes preguntas o problemas con la aplicación, busca una solución en el {subreddit} primero. Luego, si no encuentras nada puedes hacer un post con tu problema en el subreddit.`, text: `Si tienes preguntas o problemas con la aplicación, busca una solución en el {subreddit} primero. Luego, si no encuentras nada puedes hacer un post con tu problema en el subreddit.`,
subreddit: 'subreddit' subreddit: 'subreddit'
}, },
beforeReporting: 'Antes de informar de un error asegúrese de que está ejecutando la última versión de la aplicación y que lo que quiere informar es en realidad un error y no algo que está mal sólo en su extremo.', beforeReporting:
beSure: 'Asegúrate de que el fallo es reproducible en otras máquinas y también <strong>NO</strong> reporte un fallo si ya ha sido reportado.', 'Antes de informar de un error asegúrese de que está ejecutando la última versión de la aplicación y que lo que quiere informar es en realidad un error y no algo que está mal sólo en su extremo.',
beSure:
'Asegúrate de que el fallo es reproducible en otras máquinas y también <strong>NO</strong> reporte un fallo si ya ha sido reportado.',
duplicateReports: 'Los informes de errores duplicados se cerrarán, así que manténgase al tanto de eso.', duplicateReports: 'Los informes de errores duplicados se cerrarán, así que manténgase al tanto de eso.',
dontOpenIssues: '<strong>NO</strong> abra problemas para hacer preguntas, hay un subreddit para eso.', dontOpenIssues: '<strong>NO</strong> abra problemas para hacer preguntas, hay un subreddit para eso.',
newUI: { newUI: {
text: `Si tienes fluidez en Python podrías intentar hacer una nueva interfaz de usuario para la aplicación usando la biblioteca base, o arreglar los errores de la biblioteca con una petición pull en el {repo}.`, text: `Si tienes fluidez en Python podrías intentar hacer una nueva interfaz de usuario para la aplicación usando la biblioteca base, o arreglar los errores de la biblioteca con una petición pull en el {repo}.`,
repo: 'repo' repo: 'repo'
}, },
acceptFeatures: 'También acepto características, pero no cosas complejas, ya que se pueden implementar directamente en la aplicación y no en la biblioteca.', acceptFeatures:
otherLanguages: '¡Si dominas otro lenguaje de programación podrías intentar portar Deemix a otros lenguajes de programación!', 'También acepto características, pero no cosas complejas, ya que se pueden implementar directamente en la aplicación y no en la biblioteca.',
otherLanguages:
'¡Si dominas otro lenguaje de programación podrías intentar portar Deemix a otros lenguajes de programación!',
understandingCode: '¿Necesitas ayuda para entender el código? Sólo tienes que poner RemixDev en Telegram o Reddit.', understandingCode: '¿Necesitas ayuda para entender el código? Sólo tienes que poner RemixDev en Telegram o Reddit.',
contributeWebUI: { contributeWebUI: {
text: `Si conoces Vue.js (JavaScript), HTML o CSS podrías contribuir a la {webui}.`, text: `Si conoces Vue.js (JavaScript), HTML o CSS podrías contribuir a la {webui}.`,
webui: 'WebUI' webui: 'WebUI'
}, },
itsFree: 'Debes recordar que <strong>este es un proyecto libre</strong> y <strong>debes apoyar a los artistas que amas</strong> antes de apoyar a los desarrolladores.', itsFree:
'Debes recordar que <strong>este es un proyecto libre</strong> y <strong>debes apoyar a los artistas que amas</strong> 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: { lincensedUnder: {
text: `Esta obra está autorizada bajo una {gpl3}.`, text: `Esta obra está autorizada bajo una {gpl3}.`,
@ -114,10 +120,12 @@ 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: '¡Pista no encontrada a la tasa de bits deseada y no se ha encontrado ninguna alternativa!', wrongBitrateNoAlternative:
'¡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: '¡La pista no está disponible en los servidores de Deezer y no se ha encontrado ninguna alternativa!', notAvailableNoAlternative:
'¡La pista no está disponible en los servidores de Deezer y no se ha encontrado ninguna alternativa!',
noSpaceLeft: '¡No queda espacio en el dispositivo!' noSpaceLeft: '¡No queda espacio en el dispositivo!'
} }
}, },
@ -138,7 +146,8 @@ 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: '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.', 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.',
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: {
@ -158,7 +167,8 @@ const es = {
}, },
search: { search: {
startSearching: '¡Comienza a buscar!', startSearching: '¡Comienza a buscar!',
description: 'Puedes buscar un tema, un álbum entero, un artista, una lista de reproducción... ¡todo! También puedes pegar un enlace de Deezer', description:
'Puedes buscar un tema, un álbum entero, un artista, una lista de reproducción... ¡todo! También puedes pegar un enlace de Deezer',
fans: '{n} fans', fans: '{n} fans',
noResults: 'Ningun resultado', noResults: 'Ningun resultado',
noResultsTrack: 'No se encontraron pistas', noResultsTrack: 'No se encontraron pistas',
@ -278,7 +288,8 @@ const es = {
jpegImageQuality: 'Calidad de la imagen JPEG', jpegImageQuality: 'Calidad de la imagen JPEG',
embeddedArtworkPNG: 'Guardar las imágenes incrustadas como PNG', embeddedArtworkPNG: 'Guardar las imágenes incrustadas como PNG',
embeddedPNGWarning: 'Las PNG no están oficialmente soportadas por Deezer y puedes encontrar errores.', embeddedPNGWarning: 'Las PNG no están oficialmente soportadas por Deezer y puedes encontrar errores.',
imageSizeWarning: 'Nada por encima de x1200 no es usado oficialmente por Deezer, puede que encuentres inconvenientes', imageSizeWarning:
'Nada por encima de x1200 no es usado oficialmente por Deezer, puede que encuentres inconvenientes',
coverDescriptionUTF8: 'Guardar la descripción de la portada usando UTF8 (arregla la portada de iTunes)' coverDescriptionUTF8: 'Guardar la descripción de la portada usando UTF8 (arregla la portada de iTunes)'
}, },
tags: { tags: {

View File

@ -39,11 +39,12 @@ const hr = {
license: 'Licenca' license: 'Licenca'
}, },
subtitles: { subtitles: {
bugReports: "Postoji nešto što ne radi u deemixu? Reci nam!", 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!', contributing: 'Želiš doprinijeti ovom projektu? Možeš i to čak u više načina!',
donations: 'Želiš doprijeniti odmah? Možeš donirati!' 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.', 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> što su napravili ikonu.`, thanks: `Hvala <strong>rtonno</strong>, <strong>uhwot</strong> i <strong>lollilol</strong> što su mi pomogli s ovim projektom te <strong>BasCurtiz</strong> što su napravili ikonu.`,
upToDate: { upToDate: {
text: `Ostani u tijeku s nadogradnjama prateći {newsChannel} na Telegramu.`, text: `Ostani u tijeku s nadogradnjama prateći {newsChannel} na Telegramu.`,
@ -91,7 +92,7 @@ const hr = {
invalidURL: 'URL nije prepoznat', invalidURL: 'URL nije prepoznat',
unsupportedURL: 'URL još nije podržan', unsupportedURL: 'URL još nije podržan',
ISRCnotOnDeezer: 'Zapis ISRC još nije podržan na Deezeru', ISRCnotOnDeezer: 'Zapis ISRC još nije podržan na Deezeru',
notYourPrivatePlaylist: "Ne možete preuzeti tuđe privatne playliste.", notYourPrivatePlaylist: 'Ne možete preuzeti tuđe privatne playliste.',
spotifyDisabled: 'Spotify značajke nisu podešene ispravno.', spotifyDisabled: 'Spotify značajke nisu podešene ispravno.',
trackNotOnDeezer: 'Pjesma nije pronađena na Deezeru!', trackNotOnDeezer: 'Pjesma nije pronađena na Deezeru!',
albumNotOnDeezer: 'Album nije pronađen na Deezeru!', albumNotOnDeezer: 'Album nije pronađen na Deezeru!',
@ -101,8 +102,8 @@ const hr = {
wrongBitrate: 'Pjesma nije pronađena u željenom bitrateu.', wrongBitrate: 'Pjesma nije pronađena u željenom bitrateu.',
wrongBitrateNoAlternative: 'Pjesma nije pronađena u željenom bitrateu i nije pronađena alternativa!', wrongBitrateNoAlternative: 'Pjesma nije pronađena u željenom bitrateu i nije pronađena alternativa!',
no360RA: 'Pjesma nije dostupna u Reality Audio 360.', no360RA: 'Pjesma nije dostupna u Reality Audio 360.',
notAvailable: "Pjesma nije dostupna na Deezerovim serverima!", notAvailable: 'Pjesma nije dostupna na Deezerovim serverima!',
notAvailableNoAlternative: "Pjesma nije dostupna na Deezerovim serverima i alternativa nije pronađena!" notAvailableNoAlternative: 'Pjesma nije dostupna na Deezerovim serverima i alternativa nije pronađena!'
} }
}, },
favorites: { favorites: {
@ -123,7 +124,7 @@ const hr = {
linkAnalyzer: { linkAnalyzer: {
info: 'Ovu sekciju možete koristiti kako biste saznali više informacija o linku koji pokušavate preuzeti.', info: 'Ovu sekciju možete koristiti kako biste saznali više informacija o linku koji pokušavate preuzeti.',
useful: 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.", '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', linkNotSupported: 'Ovaj link još nije podržan',
linkNotSupportedYet: 'Čini se da ovaj link još nije podržan, pokušaj analizirati neki drugi.', linkNotSupportedYet: 'Čini se da ovaj link još nije podržan, pokušaj analizirati neki drugi.',
table: { table: {
@ -163,7 +164,7 @@ const hr = {
loggingIn: 'Prijavljivanje...', loggingIn: 'Prijavljivanje...',
loggedIn: 'Prijavljeni', loggedIn: 'Prijavljeni',
alreadyLogged: 'Već prijavljeni', alreadyLogged: 'Već prijavljeni',
loginFailed: "Prijava nije bila moguća", loginFailed: 'Prijava nije bila moguća',
loggedOut: 'Odjavljeni', loggedOut: 'Odjavljeni',
cancellingCurrentItem: 'Otkazujem trenutnu stavku.', cancellingCurrentItem: 'Otkazujem trenutnu stavku.',
currentItemCancelled: 'Trenutna stavka otkazana.', currentItemCancelled: 'Trenutna stavka otkazana.',
@ -228,7 +229,7 @@ const hr = {
overwriteFile: { overwriteFile: {
title: 'Trebam li prepisati datoteke?', title: 'Trebam li prepisati datoteke?',
y: 'Da, prepiši datoteke', y: 'Da, prepiši datoteke',
n: "Ne, nemoj prepisati datoteke", n: 'Ne, nemoj prepisati datoteke',
t: 'Prepiši samo oznake', t: 'Prepiši samo oznake',
b: 'Ne, zadrži obje datoteke i dodaj broj duplikatu' b: 'Ne, zadrži obje datoteke i dodaj broj duplikatu'
}, },

View File

@ -39,11 +39,12 @@ const id = {
license: 'Lisensi' license: 'Lisensi'
}, },
subtitles: { subtitles: {
bugReports: "Ada yang tidak bekerja dengan baik di deemix? Beri tahu kami!", bugReports: 'Ada yang tidak bekerja dengan baik di deemix? Beri tahu kami!',
contributing: 'Mau kontribusi dalam proyek ini? Kamu bisa lakukan dengan banyak hal!', contributing: 'Mau kontribusi dalam proyek ini? Kamu bisa lakukan dengan banyak hal!',
donations: 'Mau kontribusi secara finansial? Kamu bisa beri donasi!' donations: 'Mau kontribusi secara finansial? Kamu bisa beri donasi!'
}, },
usesLibrary: 'Aplikasi ini menggunakan pustaka <strong>deemix</strong>, yang bisa kamu gunakan untuk membuat UI deemix milikmu sendiri.', usesLibrary:
'Aplikasi ini menggunakan pustaka <strong>deemix</strong>, yang bisa kamu gunakan untuk membuat UI deemix milikmu sendiri.',
thanks: `Terima kasih kepada <strong>rtonno</strong>, <strong>uhwot</strong> dan <strong>lollilol</strong> yang telah membantuku dalam proyek ini, serta kepada <strong>BasCurtiz</strong> yang telah membuat ikon.`, thanks: `Terima kasih kepada <strong>rtonno</strong>, <strong>uhwot</strong> dan <strong>lollilol</strong> yang telah membantuku dalam proyek ini, serta kepada <strong>BasCurtiz</strong> yang telah membuat ikon.`,
upToDate: { upToDate: {
text: `Ikuti {newsChannel} di Telegram agar tidak ketinggalan berita terbaru.`, text: `Ikuti {newsChannel} di Telegram agar tidak ketinggalan berita terbaru.`,
@ -91,7 +92,7 @@ const id = {
invalidURL: 'URL tidak dikenal', invalidURL: 'URL tidak dikenal',
unsupportedURL: 'URL belum didukung', unsupportedURL: 'URL belum didukung',
ISRCnotOnDeezer: 'Lagu ISRC tidak tersedia di deezer', ISRCnotOnDeezer: 'Lagu ISRC tidak tersedia di deezer',
notYourPrivatePlaylist: "Kamu tidak bisa mengunduh daftar putar privat orang lain.", notYourPrivatePlaylist: 'Kamu tidak bisa mengunduh daftar putar privat orang lain.',
spotifyDisabled: 'Fitur Spotify tidak diatur dengan benar.', spotifyDisabled: 'Fitur Spotify tidak diatur dengan benar.',
trackNotOnDeezer: 'Lagu tidak ditemukan di deezer!', trackNotOnDeezer: 'Lagu tidak ditemukan di deezer!',
albumNotOnDeezer: 'Album tidak ditemukan di deezer!', albumNotOnDeezer: 'Album tidak ditemukan di deezer!',
@ -101,8 +102,8 @@ const id = {
wrongBitrate: 'Lagu tidak tersedia pada bitrate yang diinginkan.', wrongBitrate: 'Lagu tidak tersedia pada bitrate yang diinginkan.',
wrongBitrateNoAlternative: 'Lagu tidak tersedia pada bitrate yang diinginkan dan tidak ada alternatif lain!', wrongBitrateNoAlternative: 'Lagu tidak tersedia pada bitrate yang diinginkan dan tidak ada alternatif lain!',
no360RA: 'Lagu tidak tersedia pada Reality Audio 360.', no360RA: 'Lagu tidak tersedia pada Reality Audio 360.',
notAvailable: "Lagu tidak tersedia pada server deezer!", notAvailable: 'Lagu tidak tersedia pada server deezer!',
notAvailableNoAlternative: "Lagu tidak tersedia pada server deezer dan tidak ada alternatif lain!" notAvailableNoAlternative: 'Lagu tidak tersedia pada server deezer dan tidak ada alternatif lain!'
} }
}, },
favorites: { favorites: {
@ -123,7 +124,7 @@ const id = {
linkAnalyzer: { linkAnalyzer: {
info: 'Di sini, kamu bisa mencari informasi lebih lanjut tentang tautan yang ingin kamu unduh.', info: 'Di sini, kamu bisa mencari informasi lebih lanjut tentang tautan yang ingin kamu unduh.',
useful: useful:
"Contohnya, ini dapat berguna jika kamu ingin mengunduh lagu yang tidak tersedia di negaramu dan ingin tahu di negara mana lagu itu tersedia.", 'Contohnya, ini dapat berguna jika kamu ingin mengunduh lagu yang tidak tersedia di negaramu dan ingin tahu di negara mana lagu itu tersedia.',
linkNotSupported: 'Tautan seperti ini belum didukung', linkNotSupported: 'Tautan seperti ini belum didukung',
linkNotSupportedYet: 'Sepertinya tautan ini belum didukung, silakan coba analisa tautan lain.', linkNotSupportedYet: 'Sepertinya tautan ini belum didukung, silakan coba analisa tautan lain.',
table: { table: {
@ -163,7 +164,7 @@ const id = {
loggingIn: 'Masuk', loggingIn: 'Masuk',
loggedIn: 'Telah masuk', loggedIn: 'Telah masuk',
alreadyLogged: 'Telah masuk', alreadyLogged: 'Telah masuk',
loginFailed: "Tidak bisa masuk", loginFailed: 'Tidak bisa masuk',
loggedOut: 'Belum masuk', loggedOut: 'Belum masuk',
cancellingCurrentItem: 'Membatalkan item.', cancellingCurrentItem: 'Membatalkan item.',
currentItemCancelled: 'Item telah dibatalan.', currentItemCancelled: 'Item telah dibatalan.',
@ -227,7 +228,7 @@ const id = {
overwriteFile: { overwriteFile: {
title: 'Apakah file mau ditimpa?', title: 'Apakah file mau ditimpa?',
y: 'Ya, silakan', y: 'Ya, silakan',
n: "Tidak, jangan ditimpa", n: 'Tidak, jangan ditimpa',
t: 'Timpa tag-nya saja' t: 'Timpa tag-nya saja'
}, },
fallbackBitrate: 'Rendahkan bitrate', fallbackBitrate: 'Rendahkan bitrate',

View File

@ -63,11 +63,12 @@ const ko = {
license: '이용정책' license: '이용정책'
}, },
subtitles: { subtitles: {
bugReports: "무언가 안되는 것이 있다고요? 말해주세요!", bugReports: '무언가 안되는 것이 있다고요? 말해주세요!',
contributing: '이 프로젝트에 기여하고 싶다고요? 어렵지 않아요!', contributing: '이 프로젝트에 기여하고 싶다고요? 어렵지 않아요!',
donations: '금전적으로 지원하고 싶다고요? 후원하세요!' donations: '금전적으로 지원하고 싶다고요? 후원하세요!'
}, },
usesLibrary: '이 프로그램은 <strong>deemix</strong> 라이브러리를 사용합니다, 해당 라이브러리로 자신만의 deemix를 만들 수 있습니다.', usesLibrary:
'이 프로그램은 <strong>deemix</strong> 라이브러리를 사용합니다, 해당 라이브러리로 자신만의 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: { upToDate: {
text: `새로운 업데이트 소식을 듣고 싶으면 텔레그램 {newsChannel}을 참고하세요.`, text: `새로운 업데이트 소식을 듣고 싶으면 텔레그램 {newsChannel}을 참고하세요.`,
@ -115,7 +116,7 @@ const ko = {
unsupportedURL: 'URL 지원 누락', unsupportedURL: 'URL 지원 누락',
invalidURL: 'URL 인식 실패', invalidURL: 'URL 인식 실패',
ISRCnotOnDeezer: '트랙 코드 식별이 불가능합니다', ISRCnotOnDeezer: '트랙 코드 식별이 불가능합니다',
notYourPrivatePlaylist: "다른 사람의 비공개 재생 목록을 다운로드 할 수 없습니다.", notYourPrivatePlaylist: '다른 사람의 비공개 재생 목록을 다운로드 할 수 없습니다.',
spotifyDisabled: '스포티파이 기능이 올바르게 설정되지 않았습니다.', spotifyDisabled: '스포티파이 기능이 올바르게 설정되지 않았습니다.',
trackNotOnDeezer: 'Deezer에서 트랙을 찾을 수 없습니다!', trackNotOnDeezer: 'Deezer에서 트랙을 찾을 수 없습니다!',
albumNotOnDeezer: 'Deezer에서 앨범을 찾을 수 없습니다!', albumNotOnDeezer: 'Deezer에서 앨범을 찾을 수 없습니다!',
@ -125,10 +126,10 @@ const ko = {
wrongBitrate: '요구하는 비트레이트의 트랙을 찾을 수 없습니다.', wrongBitrate: '요구하는 비트레이트의 트랙을 찾을 수 없습니다.',
wrongBitrateNoAlternative: '요구하는 비트레이트를 찾을 수 없을 뿐더러 대체할 것을 찾지 못했습니다!', wrongBitrateNoAlternative: '요구하는 비트레이트를 찾을 수 없을 뿐더러 대체할 것을 찾지 못했습니다!',
no360RA: '해당 트랙은 360 리얼리티 오디오에 존재하지 않습니다.', no360RA: '해당 트랙은 360 리얼리티 오디오에 존재하지 않습니다.',
notAvailable: "해당 트랙은 Deezer 서버에 존재하지 않습니다!", notAvailable: '해당 트랙은 Deezer 서버에 존재하지 않습니다!',
notAvailableNoAlternative: "해당 트랙은 Deezer 서버에 존재하지 않을 뿐더러 대체할 것을 찾지 못했습니다!", notAvailableNoAlternative: '해당 트랙은 Deezer 서버에 존재하지 않을 뿐더러 대체할 것을 찾지 못했습니다!',
noSpaceLeft: "장치에 여유 공간이 없습니다!", noSpaceLeft: '장치에 여유 공간이 없습니다!',
albumDoesntExists: "트랙의 앨범이 존재하지 않습니다, 정보 수집에 실패했습니다." albumDoesntExists: '트랙의 앨범이 존재하지 않습니다, 정보 수집에 실패했습니다.'
} }
}, },
favorites: { favorites: {
@ -148,7 +149,7 @@ const ko = {
}, },
linkAnalyzer: { linkAnalyzer: {
info: '이 항목에서는 다운로드를 시도할 링크에 대한 더 많은 정보를 찾을 수 있습니다.', info: '이 항목에서는 다운로드를 시도할 링크에 대한 더 많은 정보를 찾을 수 있습니다.',
useful: "접속한 국가에서는 재생할 수 없는 특정 트랙을 다운로드 하기 위해서 가능한 국가를 찾는데 유용하게 쓰입니다.", useful: '접속한 국가에서는 재생할 수 없는 특정 트랙을 다운로드 하기 위해서 가능한 국가를 찾는데 유용하게 쓰입니다.',
linkNotSupported: '해당 링크는 아직 지원하지 않습니다', linkNotSupported: '해당 링크는 아직 지원하지 않습니다',
linkNotSupportedYet: '해당 링크는 아직 지원하지 않습니다, 다른 링크로 시도해보세요.', linkNotSupportedYet: '해당 링크는 아직 지원하지 않습니다, 다른 링크로 시도해보세요.',
@ -192,7 +193,7 @@ const ko = {
loggingIn: '로그인 하는 중...', loggingIn: '로그인 하는 중...',
loggedIn: '로그인 되었습니다', loggedIn: '로그인 되었습니다',
alreadyLogged: '이미 로그인되어 있습니다', alreadyLogged: '이미 로그인되어 있습니다',
loginFailed: "로그인 할 수 없습니다", loginFailed: '로그인 할 수 없습니다',
loggedOut: '로그아웃 하였습니다', loggedOut: '로그아웃 하였습니다',
cancellingCurrentItem: '현재 항목을 취소 중입니다.', cancellingCurrentItem: '현재 항목을 취소 중입니다.',
currentItemCancelled: '항목이 취소되었습니다.', currentItemCancelled: '항목이 취소되었습니다.',
@ -265,10 +266,10 @@ const ko = {
overwriteFile: { overwriteFile: {
title: '파일을 덮어쓸까요?', title: '파일을 덮어쓸까요?',
y: '네, 파일을 덮어쓰세요', y: '네, 파일을 덮어쓰세요',
n: "아뇨, 파일을 덮어쓰지 마세요", n: '아뇨, 파일을 덮어쓰지 마세요',
t: '태그만 덮어쓰세요', t: '태그만 덮어쓰세요',
b: '아뇨, 양쪽 다 놔두고 중복되는 파일에 번호를 추가하세요', b: '아뇨, 양쪽 다 놔두고 중복되는 파일에 번호를 추가하세요',
e: "아뇨, 확장명을 변경하세요" e: '아뇨, 확장명을 변경하세요'
}, },
fallbackBitrate: '비트레이트 대비책', fallbackBitrate: '비트레이트 대비책',
fallbackSearch: '검색 대비책', fallbackSearch: '검색 대비책',

View File

@ -55,11 +55,12 @@ const ph = {
license: 'Lisensiya' license: 'Lisensiya'
}, },
subtitles: { subtitles: {
bugReports: "Meron bang hindi gumagana sa deemix? Ipaalam mo sa amin!", bugReports: 'Meron bang hindi gumagana sa deemix? Ipaalam mo sa amin!',
contributing: 'Gusto mo bang tumulong sa proyektong ito? Pwede mong gawin iyan sa maraming paraan!', contributing: 'Gusto mo bang tumulong sa proyektong ito? Pwede mong gawin iyan sa maraming paraan!',
donations: 'Gusto mo bang tumulong sa pamamagitan ng pera? Pwede kang magbigay ng donasiyon!' donations: 'Gusto mo bang tumulong sa pamamagitan ng pera? Pwede kang magbigay ng donasiyon!'
}, },
usesLibrary: 'Ang app na ito ay gumagamit ng library galing sa <strong>deemix</strong>, na kung saan ay pwede mong gamitin para gumawa ng sarili mong UI ng deemix.', usesLibrary:
'Ang app na ito ay gumagamit ng library galing sa <strong>deemix</strong>, na kung saan ay pwede mong gamitin para gumawa ng sarili mong UI ng deemix.',
thanks: `Salamat kay <strong>rtonno</strong>, <strong>uhwot</strong> at <strong>lollilol</strong> sa pagtulong sa akin para sa proyektong ito at kay <strong>BasCurtiz</strong> sa paggawa ng icon.`, thanks: `Salamat kay <strong>rtonno</strong>, <strong>uhwot</strong> at <strong>lollilol</strong> sa pagtulong sa akin para sa proyektong ito at kay <strong>BasCurtiz</strong> sa paggawa ng icon.`,
upToDate: { upToDate: {
text: `Huwag magpapahuli sa mga update patungkol dito sa pamamagitan ng pagsali sa {newsChannel} sa Telegram.`, text: `Huwag magpapahuli sa mga update patungkol dito sa pamamagitan ng pagsali sa {newsChannel} sa Telegram.`,
@ -107,7 +108,7 @@ const ph = {
invalidURL: 'Hindi makilala ang URL', invalidURL: 'Hindi makilala ang URL',
unsupportedURL: 'Hindi pa suportado ang URL', unsupportedURL: 'Hindi pa suportado ang URL',
ISRCnotOnDeezer: 'Ang Track ISRC ay hindi pwede sa Deezer', ISRCnotOnDeezer: 'Ang Track ISRC ay hindi pwede sa Deezer',
notYourPrivatePlaylist: "Hindi pwedeng i-download ang mga pribadong playlist ng iba.", notYourPrivatePlaylist: 'Hindi pwedeng i-download ang mga pribadong playlist ng iba.',
spotifyDisabled: 'Hindi mo nai-set nang tama ang Spotify Features.', spotifyDisabled: 'Hindi mo nai-set nang tama ang Spotify Features.',
trackNotOnDeezer: 'Hindi mahanap ang track sa Deezer!', trackNotOnDeezer: 'Hindi mahanap ang track sa Deezer!',
albumNotOnDeezer: 'Hindi mahanap ang album sa Deezer!', albumNotOnDeezer: 'Hindi mahanap ang album sa Deezer!',
@ -117,9 +118,9 @@ const ph = {
wrongBitrate: 'Hindi mahanap ang track sa gusto mong bitrate.', wrongBitrate: 'Hindi mahanap ang track sa gusto mong bitrate.',
wrongBitrateNoAlternative: 'Hindi mahanap ang track sa gusto mong bitrate at walang mahanap na iba!', wrongBitrateNoAlternative: 'Hindi mahanap ang track sa gusto mong bitrate at walang mahanap na iba!',
no360RA: 'Hindi pwede ang track para sa Reality Audio 360.', no360RA: 'Hindi pwede ang track para sa Reality Audio 360.',
notAvailable: "Walang available na track sa server ng Deezer!", notAvailable: 'Walang available na track sa server ng Deezer!',
notAvailableNoAlternative: "Walang available na track sa server ng Deezer at walang mahanap na iba!", notAvailableNoAlternative: 'Walang available na track sa server ng Deezer at walang mahanap na iba!',
noSpaceLeft: "Wala nang natitirang space sa iyong device!" noSpaceLeft: 'Wala nang natitirang space sa iyong device!'
} }
}, },
favorites: { favorites: {
@ -139,7 +140,8 @@ const ph = {
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'Pwede gamitin ang section na ito para sa iba pang impormasyon patungkol sa link na gusto mong i-download.', info: 'Pwede gamitin ang section na ito para sa iba pang impormasyon patungkol sa link na gusto mong i-download.',
useful: "Makatutulong ito kung meron kang gustong i-download na track na hindi available sa bansa mo at gusto mong malaman kung meron bang ganito kapag sa iba.", useful:
'Makatutulong ito kung meron kang gustong i-download na track na hindi available sa bansa mo at gusto mong malaman kung meron bang ganito kapag sa iba.',
linkNotSupported: 'Hindi pa suportado ang link', linkNotSupported: 'Hindi pa suportado ang link',
linkNotSupportedYet: 'Mukhang hindi pa suportado itong link, iba na lang ang ilagay mo.', linkNotSupportedYet: 'Mukhang hindi pa suportado itong link, iba na lang ang ilagay mo.',
table: { table: {
@ -159,7 +161,8 @@ const ph = {
}, },
search: { search: {
startSearching: 'Simulang Maghanap!', startSearching: 'Simulang Maghanap!',
description: 'Pwede kang maghanap ng track, buong album, artist, playlist.... kahit ano! Pwede ka ring mag-paste dito ng link na galing sa Deezer', description:
'Pwede kang maghanap ng track, buong album, artist, playlist.... kahit ano! Pwede ka ring mag-paste dito ng link na galing sa Deezer',
fans: '{n} mga fan', fans: '{n} mga fan',
noResults: 'Walang resulta', noResults: 'Walang resulta',
noResultsTrack: 'Walang mahanap na mga Track', noResultsTrack: 'Walang mahanap na mga Track',
@ -181,7 +184,7 @@ const ph = {
loggingIn: 'Nagla-log in...', loggingIn: 'Nagla-log in...',
loggedIn: 'Na-login na', loggedIn: 'Na-login na',
alreadyLogged: 'Nakalogin ka na', alreadyLogged: 'Nakalogin ka na',
loginFailed: "Hindi maka-log in", loginFailed: 'Hindi maka-log in',
loggedOut: 'Na-logout na', loggedOut: 'Na-logout na',
cancellingCurrentItem: 'Kinakansel ang item.', cancellingCurrentItem: 'Kinakansel ang item.',
currentItemCancelled: 'Nakansel na ang item.', currentItemCancelled: 'Nakansel na ang item.',
@ -248,10 +251,10 @@ const ph = {
overwriteFile: { overwriteFile: {
title: 'Papatungan ko ba ang file?', title: 'Papatungan ko ba ang file?',
y: 'Oo, patungan mo ang file', y: 'Oo, patungan mo ang file',
n: "Hindi, huwag mong patungan ang file", n: 'Hindi, huwag mong patungan ang file',
t: 'Patungan mo lang ang mga tag', t: 'Patungan mo lang ang mga tag',
b: 'Hindi, hayaan mo silang dalawa at lagyan mo lang ng numero sa kapareho niya', b: 'Hindi, hayaan mo silang dalawa at lagyan mo lang ng numero sa kapareho niya',
e: "Hindi, at huwag mong tignan ang mga extension" e: 'Hindi, at huwag mong tignan ang mga extension'
}, },
fallbackBitrate: 'Binabaang bitrate', fallbackBitrate: 'Binabaang bitrate',
fallbackSearch: 'Maghanap para sa binabaan', fallbackSearch: 'Maghanap para sa binabaan',
@ -279,7 +282,8 @@ const ph = {
jpegImageQuality: 'Kalidad ng JPEG na imahe', jpegImageQuality: 'Kalidad ng JPEG na imahe',
embeddedArtworkPNG: 'I-save ang nakadikit na artwork bilang PNG', embeddedArtworkPNG: 'I-save ang nakadikit na artwork bilang PNG',
embeddedPNGWarning: 'Ang mga PNG ay hindi opisyal na suportado ng Deezer at maaaring magkaroon ng bug', embeddedPNGWarning: 'Ang mga PNG ay hindi opisyal na suportado ng Deezer at maaaring magkaroon ng bug',
imageSizeWarning: 'Lahat ng mas mataas sa x1200 ay hindi opisyal na ginagamit sa Deezer, at posibleng magkaroon ng isyu', imageSizeWarning:
'Lahat ng mas mataas sa x1200 ay hindi opisyal na ginagamit sa Deezer, at posibleng magkaroon ng isyu',
coverDescriptionUTF8: 'I-save ang deskripsyon ng cover gamit ng UTF8 (iTunes Cover Fix)' coverDescriptionUTF8: 'I-save ang deskripsyon ng cover gamit ng UTF8 (iTunes Cover Fix)'
}, },
tags: { tags: {

View File

@ -55,11 +55,12 @@ const pl = {
license: 'Licencja' license: 'Licencja'
}, },
subtitles: { subtitles: {
bugReports: "Czy deemix działa inaczej niż powinien? Powiedz nam!", bugReports: 'Czy deemix działa inaczej niż powinien? Powiedz nam!',
contributing: 'Chcesz pomóc w tym projekcie? Możesz to zrobić na wiele sposobów!', contributing: 'Chcesz pomóc w tym projekcie? Możesz to zrobić na wiele sposobów!',
donations: 'Chcesz pomóc finansowo? Możesz nas wesprzeć!' donations: 'Chcesz pomóc finansowo? Możesz nas wesprzeć!'
}, },
usesLibrary: 'Ten program używa biblioteki <strong>deemix</strong>, której możesz użyć do stworzenia własnego interfejsu użytkownika', usesLibrary:
'Ten program używa biblioteki <strong>deemix</strong>, której możesz użyć do stworzenia własnego interfejsu użytkownika',
thanks: `Podziękowania dla <strong>rtonno</strong>, <strong>uhwot</strong> i <strong>lollilol</strong> za pomoc w tym projekcie oraz dla <strong>BasCurtiz</strong> za stworzenie ikony.`, thanks: `Podziękowania dla <strong>rtonno</strong>, <strong>uhwot</strong> i <strong>lollilol</strong> za pomoc w tym projekcie oraz dla <strong>BasCurtiz</strong> za stworzenie ikony.`,
upToDate: { upToDate: {
text: `Bądź na bieżąco z aktualizacjami dołączając do {newsChannel} na Telegramie.`, text: `Bądź na bieżąco z aktualizacjami dołączając do {newsChannel} na Telegramie.`,
@ -107,7 +108,7 @@ const pl = {
invalidURL: 'Nierozpoznany URL', invalidURL: 'Nierozpoznany URL',
unsupportedURL: 'Niewspierany URL', unsupportedURL: 'Niewspierany URL',
ISRCnotOnDeezer: 'ISRC nie jest dostępne na Deezerze', ISRCnotOnDeezer: 'ISRC nie jest dostępne na Deezerze',
notYourPrivatePlaylist: "Nie możesz pobierać czyichś prywatnych playlist.", notYourPrivatePlaylist: 'Nie możesz pobierać czyichś prywatnych playlist.',
spotifyDisabled: 'Funkcje Spotify nie są poprawnie ustawione', spotifyDisabled: 'Funkcje Spotify nie są poprawnie ustawione',
trackNotOnDeezer: 'Nie znaleziono utworu na Deezerze!', trackNotOnDeezer: 'Nie znaleziono utworu na Deezerze!',
albumNotOnDeezer: 'Nie znaleziono albumu na Deezerze!', albumNotOnDeezer: 'Nie znaleziono albumu na Deezerze!',
@ -117,8 +118,8 @@ const pl = {
wrongBitrate: 'Nie znaleziono utworu w wybranym bitrate.', wrongBitrate: 'Nie znaleziono utworu w wybranym bitrate.',
wrongBitrateNoAlternative: 'Nie znaleziono utworu w wybranym bitrate i nie mozna znaleźć alternatywy!', wrongBitrateNoAlternative: 'Nie znaleziono utworu w wybranym bitrate i nie mozna znaleźć alternatywy!',
no360RA: 'Utwór nie jest dostępny w Reality Audio 360.', no360RA: 'Utwór nie jest dostępny w Reality Audio 360.',
notAvailable: "Utwór nie jest dostępny na serwerach Deezera!", notAvailable: 'Utwór nie jest dostępny na serwerach Deezera!',
notAvailableNoAlternative: "Utwór nie jest dostępny na serwerach Deezera i nie można znaleźć alternatywy!" notAvailableNoAlternative: 'Utwór nie jest dostępny na serwerach Deezera i nie można znaleźć alternatywy!'
} }
}, },
favorites: { favorites: {
@ -138,7 +139,8 @@ const pl = {
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'Możesz użyć tej sekcji, aby znaleźć więcej informacji o linku, który chcesz pobrać.', info: 'Możesz użyć tej sekcji, aby znaleźć więcej informacji o linku, który chcesz pobrać.',
useful: "Jest to przydatne na przykład gdy chcesz pobrać jakieś utwory, które nie są dostępne w twoim kraju i chcesz wiedzieć gdzie są dostępne.", useful:
'Jest to przydatne na przykład gdy chcesz pobrać jakieś utwory, które nie są dostępne w twoim kraju i chcesz wiedzieć gdzie są dostępne.',
linkNotSupported: 'Ten link nie jest jeszcze wspierany', linkNotSupported: 'Ten link nie jest jeszcze wspierany',
linkNotSupportedYet: 'Wygląda na to, że ten link nie jest jeszcze wspierany. Spróbuj przeanalizować inny.', linkNotSupportedYet: 'Wygląda na to, że ten link nie jest jeszcze wspierany. Spróbuj przeanalizować inny.',
table: { table: {
@ -180,7 +182,7 @@ const pl = {
loggingIn: 'Logowanie...', loggingIn: 'Logowanie...',
loggedIn: 'Zalogowano', loggedIn: 'Zalogowano',
alreadyLogged: 'Już zalogowano', alreadyLogged: 'Już zalogowano',
loginFailed: "Nie można zalogować", loginFailed: 'Nie można zalogować',
loggedOut: 'Wylogowano', loggedOut: 'Wylogowano',
cancellingCurrentItem: 'Anulowanie przedmiotu.', cancellingCurrentItem: 'Anulowanie przedmiotu.',
currentItemCancelled: 'Anulowano przedmiot.', currentItemCancelled: 'Anulowano przedmiot.',
@ -246,7 +248,7 @@ const pl = {
overwriteFile: { overwriteFile: {
title: 'Nadpisywać pliki?', title: 'Nadpisywać pliki?',
y: 'Tak', y: 'Tak',
n: "Nie", n: 'Nie',
t: 'Tylko tagi', t: 'Tylko tagi',
b: 'Nie, dodaj numer do drugiego pliku', b: 'Nie, dodaj numer do drugiego pliku',
e: 'Nie, nie patrz na rozszerzenia' e: 'Nie, nie patrz na rozszerzenia'

View File

@ -43,7 +43,8 @@ const pt = {
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: 'Esta aplicação usa a biblioteca <strong>deemix</strong>, que poderás usar para desenvolver o teu proprio UI para o deemix.', usesLibrary:
'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> 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> por elaborarem o ícone.`,
upToDate: { upToDate: {
text: `Mantem-te atualizado seguindo o {newsChannel} no Telegram.`, text: `Mantem-te atualizado seguindo o {newsChannel} no Telegram.`,
@ -91,7 +92,7 @@ const pt = {
invalidURL: 'URL não reconhecido', invalidURL: 'URL não reconhecido',
unsupportedURL: 'URL ainda não suportado', unsupportedURL: 'URL ainda não suportado',
ISRCnotOnDeezer: 'Faixa ISRC não disponível no deezer', ISRCnotOnDeezer: 'Faixa ISRC não disponível no deezer',
notYourPrivatePlaylist: "Nao podes baixar listas de reprodução privadas de outros.", 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!',
@ -122,7 +123,8 @@ const pt = {
}, },
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: '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.', 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.',
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: {
@ -142,7 +144,8 @@ const pt = {
}, },
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:
'Podes perquisar uma música, um álbum inteiro, um artista, uma lista de reprodução... tudo! Também podes colar um link do Deezer',
fans: '{n} fãs', fans: '{n} fãs',
noResults: 'Sem resultados', noResults: 'Sem resultados',
noResultsTrack: 'Faixa não encontrada', noResultsTrack: 'Faixa não encontrada',
@ -161,7 +164,7 @@ const pt = {
loggingIn: 'A autenticar', loggingIn: 'A autenticar',
loggedIn: 'Autenticado', loggedIn: 'Autenticado',
alreadyLogged: 'Já estás autenticado', alreadyLogged: 'Já estás autenticado',
loginFailed: "Nao foi possivel iniciar sessão", loginFailed: 'Nao foi possivel iniciar sessão',
loggedOut: 'Desconectado', loggedOut: 'Desconectado',
cancellingCurrentItem: 'A cancelar item actual.', cancellingCurrentItem: 'A cancelar item actual.',
currentItemCancelled: 'Item actual cancelado.', currentItemCancelled: 'Item actual cancelado.',

View File

@ -58,11 +58,12 @@ const ru = {
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> за иконку.`, thanks: `Спасибо <strong>rtonno</strong>, <strong>uhwot</strong> и <strong>lollilol</strong> за помощь с этим проектом, а также <strong>BasCurtiz</strong> за иконку.`,
upToDate: { upToDate: {
text: `Следите за последними обновлениями на {newsChannel} в Telegram.`, text: `Следите за последними обновлениями на {newsChannel} в Telegram.`,
@ -110,7 +111,7 @@ const ru = {
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!',
@ -120,10 +121,10 @@ const ru = {
wrongBitrate: 'Данного трека нет в нужном битрейте.', wrongBitrate: 'Данного трека нет в нужном битрейте.',
wrongBitrateNoAlternative: 'Данного трека нет в нужном битрейте. Альтернатив не найдено!', wrongBitrateNoAlternative: 'Данного трека нет в нужном битрейте. Альтернатив не найдено!',
no360RA: 'Трек недоступен в формате Reality Audio 360.', no360RA: 'Трек недоступен в формате Reality Audio 360.',
notAvailable: "Трек недоступен на серверах Deezer!", notAvailable: 'Трек недоступен на серверах Deezer!',
notAvailableNoAlternative: "Трек недоступен на серверах Deezer. Альтернатив не найдено!", notAvailableNoAlternative: 'Трек недоступен на серверах Deezer. Альтернатив не найдено!',
noSpaceLeft: "На устройстве не осталось свободного места!", noSpaceLeft: 'На устройстве не осталось свободного места!',
albumDoesntExists: "Альбома не существует, информация не получена" albumDoesntExists: 'Альбома не существует, информация не получена'
} }
}, },
favorites: { favorites: {
@ -143,7 +144,8 @@ const ru = {
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'Используйте этот раздел, чтобы узнать информацию о ссылке, которую требуется скачать.', info: 'Используйте этот раздел, чтобы узнать информацию о ссылке, которую требуется скачать.',
useful: "Этот раздел нужен, если вы хотите загрузить треки, недоступные в вашей стране, а также посмотреть, где они доступны.", useful:
'Этот раздел нужен, если вы хотите загрузить треки, недоступные в вашей стране, а также посмотреть, где они доступны.',
linkNotSupported: 'Ссылка не поддерживается', linkNotSupported: 'Ссылка не поддерживается',
linkNotSupportedYet: 'Эта ссылка не поддерживается, попробуйте вставить другую.', linkNotSupportedYet: 'Эта ссылка не поддерживается, попробуйте вставить другую.',
table: { table: {
@ -185,7 +187,7 @@ const ru = {
loggingIn: 'Вход...', loggingIn: 'Вход...',
loggedIn: 'Вход выполнен', loggedIn: 'Вход выполнен',
alreadyLogged: 'Вход уже выполнен', alreadyLogged: 'Вход уже выполнен',
loginFailed: "Вход не выполнен", loginFailed: 'Вход не выполнен',
loggedOut: 'Вы вышли из аккаунта', loggedOut: 'Вы вышли из аккаунта',
cancellingCurrentItem: 'Отмена текущей загрузки.', cancellingCurrentItem: 'Отмена текущей загрузки.',
currentItemCancelled: 'Отменено.', currentItemCancelled: 'Отменено.',
@ -255,10 +257,10 @@ const ru = {
overwriteFile: { overwriteFile: {
title: 'Нужно ли перезаписывать файлы?', title: 'Нужно ли перезаписывать файлы?',
y: 'Да, перезаписать файл', y: 'Да, перезаписать файл',
n: "Нет, не перезаписывать", n: 'Нет, не перезаписывать',
t: 'Обновить только теги', t: 'Обновить только теги',
b: 'Нет, оставить оба файла и добавить номер к дубликату', b: 'Нет, оставить оба файла и добавить номер к дубликату',
e: "Нет, вне зависимости от расширения" e: 'Нет, вне зависимости от расширения'
}, },
fallbackBitrate: 'Загружать с битрейтом ниже, если текущий недоступен', fallbackBitrate: 'Загружать с битрейтом ниже, если текущий недоступен',
fallbackSearch: 'Искать похожий трек, если запрашиваемый недоступен', fallbackSearch: 'Искать похожий трек, если запрашиваемый недоступен',

View File

@ -39,11 +39,12 @@ const vn = {
license: 'Bằng phép' license: 'Bằng phép'
}, },
subtitles: { 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!", 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!', 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!' 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.', 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ới việc thiết kế biểu tượng.`, 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ới việc thiết kế biểu tượng.`,
upToDate: { upToDate: {
text: `Cập nhật app bằng cách theo dõi {newsChannel} trên Telegram.`, text: `Cập nhật app bằng cách theo dõi {newsChannel} trên Telegram.`,
@ -91,7 +92,7 @@ const vn = {
invalidURL: 'Không nhận diện được URL', invalidURL: 'Không nhận diện được URL',
unsupportedURL: 'URL này chưa được hỗ trợ', 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', 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.", 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.', 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!', trackNotOnDeezer: 'Bài hát không có trên Deezer!',
albumNotOnDeezer: 'Album không có trên Deezer!', albumNotOnDeezer: 'Album không có trên Deezer!',
@ -101,8 +102,8 @@ const vn = {
wrongBitrate: 'Bài hát này không có ở bitrate bạn muốn.', 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!', 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.', 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!", 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!" 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: { favorites: {
@ -123,7 +124,7 @@ const vn = {
linkAnalyzer: { 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.', 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: 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ợ.", '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ợ', 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.', 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: { table: {
@ -143,8 +144,7 @@ const vn = {
}, },
search: { search: {
startSearching: 'Bắt đầu tìm kiếm!', startSearching: 'Bắt đầu tìm kiếm!',
description: 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',
'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: '{n} người hâm mộ', fans: '{n} người hâm mộ',
noResults: 'Không có kết quả', noResults: 'Không có kết quả',
noResultsTrack: 'Không tìm được bài hát nào', noResultsTrack: 'Không tìm được bài hát nào',
@ -163,7 +163,7 @@ const vn = {
loggingIn: 'Đang đăng nhập', loggingIn: 'Đang đăng nhập',
loggedIn: 'Đăng nhập thành công', loggedIn: 'Đăng nhập thành công',
alreadyLogged: 'Đã đăng nhập', alreadyLogged: 'Đã đăng nhập',
loginFailed: "Không thể đăng nhập", loginFailed: 'Không thể đăng nhập',
loggedOut: 'Đăng xuất', loggedOut: 'Đăng xuất',
cancellingCurrentItem: 'Đang hủy file hiện tại.', cancellingCurrentItem: 'Đang hủy file hiện tại.',
currentItemCancelled: 'File hiện tại đã bị hủy.', currentItemCancelled: 'File hiện tại đã bị hủy.',
@ -228,7 +228,7 @@ const vn = {
overwriteFile: { overwriteFile: {
title: 'Tôi có nên ghi đè file này không?', title: 'Tôi có nên ghi đè file này không?',
y: 'Có, hãy ghi đè file này', y: 'Có, hãy ghi đè file này',
n: "Không, đừng ghi đè file này", n: 'Không, đừng ghi đè file này',
t: 'Chỉ ghi đè các tag' t: 'Chỉ ghi đè các tag'
}, },
fallbackBitrate: 'Bitrate dự phòng', fallbackBitrate: 'Bitrate dự phòng',

View File

@ -63,7 +63,7 @@ const zh_tw = {
license: '使用許可' license: '使用許可'
}, },
subtitles: { subtitles: {
bugReports: "使用 deemix 時,遇到了什麼問題嗎?歡迎回報錯誤!", bugReports: '使用 deemix 時,遇到了什麼問題嗎?歡迎回報錯誤!',
contributing: '您想替這個專案提出貢獻嗎?您可以透過許多不同的方式來幫忙!', contributing: '您想替這個專案提出貢獻嗎?您可以透過許多不同的方式來幫忙!',
donations: '您想要捐款嗎?可以贊助我們!' donations: '您想要捐款嗎?可以贊助我們!'
}, },
@ -115,7 +115,7 @@ const zh_tw = {
invalidURL: '無法識別網址', invalidURL: '無法識別網址',
unsupportedURL: '尚不支持此網址', unsupportedURL: '尚不支持此網址',
ISRCnotOnDeezer: '無法在 Deezer 上使用單曲 ISRC', ISRCnotOnDeezer: '無法在 Deezer 上使用單曲 ISRC',
notYourPrivatePlaylist: "您無法下載他人的私人播放清單。", notYourPrivatePlaylist: '您無法下載他人的私人播放清單。',
spotifyDisabled: 'Spotify 功能未正確設定。', spotifyDisabled: 'Spotify 功能未正確設定。',
trackNotOnDeezer: '在 Deezer 上找不到此歌曲!', trackNotOnDeezer: '在 Deezer 上找不到此歌曲!',
albumNotOnDeezer: '在 Deezer 上找不到此專輯!', albumNotOnDeezer: '在 Deezer 上找不到此專輯!',
@ -125,10 +125,10 @@ const zh_tw = {
wrongBitrate: '找不到符合所設位元率的歌曲。', wrongBitrate: '找不到符合所設位元率的歌曲。',
wrongBitrateNoAlternative: '找不到符合所設位元率的歌曲,且無法找到其他替代歌曲!', wrongBitrateNoAlternative: '找不到符合所設位元率的歌曲,且無法找到其他替代歌曲!',
no360RA: '本歌曲並不支援 Reality Audio 360。', no360RA: '本歌曲並不支援 Reality Audio 360。',
notAvailable: "無法在 Deezer 伺服器載入此歌曲!", notAvailable: '無法在 Deezer 伺服器載入此歌曲!',
notAvailableNoAlternative: "無法在 Deezer 伺服器載入此歌曲,且無法找到其他替代歌曲!", notAvailableNoAlternative: '無法在 Deezer 伺服器載入此歌曲,且無法找到其他替代歌曲!',
noSpaceLeft: "本裝置可用空間已用盡!", noSpaceLeft: '本裝置可用空間已用盡!',
albumDoesntExists: "本歌曲的專輯不存在,無法取得資訊" albumDoesntExists: '本歌曲的專輯不存在,無法取得資訊'
} }
}, },
favorites: { favorites: {
@ -148,8 +148,7 @@ const zh_tw = {
}, },
linkAnalyzer: { linkAnalyzer: {
info: '您可以透過此工具取得您所想下載的連結的相關資訊。', info: '您可以透過此工具取得您所想下載的連結的相關資訊。',
useful: useful: '比如,當您所想下載的歌曲無法在您的國家播放,且您想知道哪些國家可以播放此歌曲時,您可使用此工具。',
"比如,當您所想下載的歌曲無法在您的國家播放,且您想知道哪些國家可以播放此歌曲時,您可使用此工具。",
linkNotSupported: '尚未支援此連結', linkNotSupported: '尚未支援此連結',
linkNotSupportedYet: '我們似乎尚未支援此連結,請改用其他連結。', linkNotSupportedYet: '我們似乎尚未支援此連結,請改用其他連結。',
table: { table: {
@ -169,8 +168,7 @@ const zh_tw = {
}, },
search: { search: {
startSearching: '開始搜尋!', startSearching: '開始搜尋!',
description: description: '您可以搜索歌曲名稱、專輯、藝人、播放清單...等等。您也可以直接貼上 Deezer 網址。',
'您可以搜索歌曲名稱、專輯、藝人、播放清單...等等。您也可以直接貼上 Deezer 網址。',
fans: '{n} 個粉絲', fans: '{n} 個粉絲',
noResults: '無搜尋結果', noResults: '無搜尋結果',
noResultsTrack: '找不到歌曲', noResultsTrack: '找不到歌曲',
@ -192,7 +190,7 @@ const zh_tw = {
loggingIn: '登入中...', loggingIn: '登入中...',
loggedIn: '登入', loggedIn: '登入',
alreadyLogged: '已登入', alreadyLogged: '已登入',
loginFailed: "無法登入", loginFailed: '無法登入',
loggedOut: '登出', loggedOut: '登出',
cancellingCurrentItem: '取消當前項目。', cancellingCurrentItem: '取消當前項目。',
currentItemCancelled: '當前項目已取消。', currentItemCancelled: '當前項目已取消。',
@ -262,10 +260,10 @@ const zh_tw = {
overwriteFile: { overwriteFile: {
title: '是否要覆蓋檔案?', title: '是否要覆蓋檔案?',
y: '是,覆蓋檔案', y: '是,覆蓋檔案',
n: "否,請勿覆蓋檔案", n: '否,請勿覆蓋檔案',
t: '僅覆蓋標籤', t: '僅覆蓋標籤',
b: '否,保留兩個檔案並在重複的檔名中加入一個數字', b: '否,保留兩個檔案並在重複的檔名中加入一個數字',
e: "否,不顧慮附檔名" e: '否,不顧慮附檔名'
}, },
fallbackBitrate: '當偏好位元率無法下載時,下載其他版本', fallbackBitrate: '當偏好位元率無法下載時,下載其他版本',
fallbackSearch: '當搜尋結果無法使用時,使用其他搜尋結果', fallbackSearch: '當搜尋結果無法使用時,使用其他搜尋結果',

View File

@ -20,9 +20,9 @@ const i18n = new VueI18n({
* @param {number} choicesLength An overall amount of available choices * @param {number} choicesLength An overall amount of available choices
* @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(choice, choicesLength) {
var n = Math.abs(choice) % 100 const n = Math.abs(choice) % 100
var n1 = n % 10 const n1 = n % 10
if (n > 10 && n < 20) { if (n > 10 && n < 20) {
return 2 return 2

View File

@ -80,7 +80,7 @@ const mutations = {
}, },
RESET_LOGIN(state) { RESET_LOGIN(state) {
// Needed for reactivity // Needed for reactivity
let clientMode = state.clientMode const clientMode = state.clientMode
Object.assign(state, getDefaultState()) Object.assign(state, getDefaultState())
state.clientMode = clientMode state.clientMode = clientMode
} }

View File

@ -5,7 +5,7 @@ export function fetchData(key, data = {}, method = 'GET') {
url.searchParams.append(key, data[key]) url.searchParams.append(key, data[key])
}) })
return fetch(url.href, {method}) return fetch(url.href, { method })
.then(response => response.json()) .then(response => response.json())
.catch(() => {}) .catch(() => {})
} }

View File

@ -1,6 +1,6 @@
export const COUNTRIES = { export const COUNTRIES = {
AF: 'Afghanistan', AF: 'Afghanistan',
AX: '\u00c5land Islands', AX: '\u00C5land Islands',
AL: 'Albania', AL: 'Albania',
DZ: 'Algeria', DZ: 'Algeria',
AS: 'American Samoa', AS: 'American Samoa',
@ -53,10 +53,10 @@ export const COUNTRIES = {
CD: 'Congo, the Democratic Republic of the', CD: 'Congo, the Democratic Republic of the',
CK: 'Cook Islands', CK: 'Cook Islands',
CR: 'Costa Rica', CR: 'Costa Rica',
CI: "C\u00f4te d'Ivoire", CI: "C\u00F4te d'Ivoire",
HR: 'Croatia', HR: 'Croatia',
CU: 'Cuba', CU: 'Cuba',
CW: 'Cura\u00e7ao', CW: 'Cura\u00E7ao',
CY: 'Cyprus', CY: 'Cyprus',
CZ: 'Czech Republic', CZ: 'Czech Republic',
DK: 'Denmark', DK: 'Denmark',
@ -179,11 +179,11 @@ export const COUNTRIES = {
PT: 'Portugal', PT: 'Portugal',
PR: 'Puerto Rico', PR: 'Puerto Rico',
QA: 'Qatar', QA: 'Qatar',
RE: 'R\u00e9union', RE: 'R\u00E9union',
RO: 'Romania', RO: 'Romania',
RU: 'Russian Federation', RU: 'Russian Federation',
RW: 'Rwanda', RW: 'Rwanda',
BL: 'Saint Barth\u00e9lemy', BL: 'Saint Barth\u00E9lemy',
SH: 'Saint Helena, Ascension and Tristan da Cunha', SH: 'Saint Helena, Ascension and Tristan da Cunha',
KN: 'Saint Kitts and Nevis', KN: 'Saint Kitts and Nevis',
LC: 'Saint Lucia', LC: 'Saint Lucia',

View File

@ -4,7 +4,7 @@
* therefore it's considered a new release, if referring to a track or album * therefore it's considered a new release, if referring to a track or album
*/ */
export function checkNewRelease(dateToCheck) { export function checkNewRelease(dateToCheck) {
let now = new Date() const now = new Date()
now.setHours(0, 0, 0, 0) now.setHours(0, 0, 0, 0)
dateToCheck = new Date(dateToCheck) dateToCheck = new Date(dateToCheck)

View File

@ -11,7 +11,7 @@ export function sendAddToQueue(url, bitrate = null) {
} }
export function aggregateDownloadLinks(releases) { export function aggregateDownloadLinks(releases) {
let links = [] const links = []
releases.forEach(release => { releases.forEach(release => {
links.push(release.link) links.push(release.link)

View File

@ -3,13 +3,15 @@ class CustomSocket extends WebSocket {
super(args) super(args)
this.listeners = {} this.listeners = {}
} }
emit(key, data) { emit(key, data) {
if (this.readyState !== WebSocket.OPEN) return false if (this.readyState !== WebSocket.OPEN) return false
this.send(JSON.stringify({ key, data })) this.send(JSON.stringify({ key, data }))
} }
on(key, cb) { on(key, cb) {
if (Object.keys(this.listeners).indexOf(key) == -1){ if (!Object.keys(this.listeners).includes(key)) {
console.log('on:', key) console.log('on:', key)
this.listeners[key] = cb this.listeners[key] = cb
@ -21,10 +23,10 @@ class CustomSocket extends WebSocket {
} }
}) })
} }
} }
off(key) { off(key) {
if (Object.keys(this.listeners).indexOf(key) != -1){ if (Object.keys(this.listeners).includes(key)) {
console.log('off:', key) console.log('off:', key)
this.removeEventListener('message', this.listeners[key]) this.removeEventListener('message', this.listeners[key])
delete this.listeners[key] delete this.listeners[key]

View File

@ -9,13 +9,13 @@ const sharedOptions = {
position: 'left' position: 'left'
} }
let toastsWithId = {} const toastsWithId = {}
export const toast = function(msg, icon = null, dismiss = true, id = null) { export const toast = function (msg, icon = null, dismiss = true, id = null) {
if (toastsWithId[id]) { if (toastsWithId[id]) {
let toastObj = toastsWithId[id] const toastObj = toastsWithId[id]
let toastElement = document.querySelectorAll(`div.toastify[toast_id=${id}]`) const toastElement = document.querySelectorAll(`div.toastify[toast_id=${id}]`)
if (msg) { if (msg) {
toastElement.forEach(toast => { toastElement.forEach(toast => {
@ -28,15 +28,15 @@ export const toast = function(msg, icon = null, dismiss = true, id = null) {
} }
if (icon) { if (icon) {
let iconNode = document.createElement('span') const iconNode = document.createElement('span')
iconNode.classList.add('toast-icon') iconNode.classList.add('toast-icon')
if (icon == 'loading') { if (icon == 'loading') {
let loader = document.createElement('div') const loader = document.createElement('div')
loader.classList.add('circle-loader') loader.classList.add('circle-loader')
iconNode.appendChild(loader) iconNode.appendChild(loader)
} else { } else {
let materialIcon = document.createElement('i') const materialIcon = document.createElement('i')
materialIcon.classList.add('material-icons') materialIcon.classList.add('material-icons')
materialIcon.appendChild(document.createTextNode(icon)) materialIcon.appendChild(document.createTextNode(icon))
iconNode.appendChild(materialIcon) iconNode.appendChild(materialIcon)
@ -62,41 +62,41 @@ export const toast = function(msg, icon = null, dismiss = true, id = null) {
}, 3000) }, 3000)
} }
} else { } else {
let iconNode = document.createElement('span') const iconNode = document.createElement('span')
iconNode.classList.add('toast-icon') iconNode.classList.add('toast-icon')
if (icon == null) { if (icon == null) {
iconNode.appendChild(document.createTextNode('')) iconNode.appendChild(document.createTextNode(''))
} else if (icon == 'loading') { } else if (icon == 'loading') {
let loader = document.createElement('div') const loader = document.createElement('div')
loader.classList.add('circle-loader') loader.classList.add('circle-loader')
iconNode.appendChild(loader) iconNode.appendChild(loader)
} else { } else {
let materialIcon = document.createElement('i') const materialIcon = document.createElement('i')
materialIcon.classList.add('material-icons') materialIcon.classList.add('material-icons')
materialIcon.appendChild(document.createTextNode(icon)) materialIcon.appendChild(document.createTextNode(icon))
iconNode.appendChild(materialIcon) iconNode.appendChild(materialIcon)
} }
let messageNode = document.createElement('span') const messageNode = document.createElement('span')
messageNode.classList.add('toast-message') messageNode.classList.add('toast-message')
messageNode.appendChild(document.createTextNode(msg)) messageNode.appendChild(document.createTextNode(msg))
let toastNode = document.createElement('toast') const toastNode = document.createElement('toast')
toastNode.appendChild(iconNode) toastNode.appendChild(iconNode)
toastNode.appendChild(messageNode) toastNode.appendChild(messageNode)
let toastObj = Toastify({ const toastObj = Toastify({
...sharedOptions, ...sharedOptions,
node: toastNode, node: toastNode,
duration: dismiss ? 3000 : 0, duration: dismiss ? 3000 : 0,
className: dismiss ? 'dismissable' : '', className: dismiss ? 'dismissable' : '',
onClick: function() { onClick() {
let dismissable = true let dismissable = true
if (id) { if (id) {
let toastClasses = document.querySelector(`div.toastify[toast_id=${id}]`).classList const toastClasses = document.querySelector(`div.toastify[toast_id=${id}]`).classList
if (toastClasses) { if (toastClasses) {
dismissable = Array.prototype.slice.call(toastClasses).indexOf('dismissable') != -1 dismissable = Array.prototype.slice.call(toastClasses).includes('dismissable')
} }
} }
if (toastObj && dismissable) { if (toastObj && dismissable) {
@ -108,7 +108,7 @@ export const toast = function(msg, icon = null, dismiss = true, id = null) {
} }
}, },
offset: { offset: {
x: 'true' === localStorage.getItem('slimSidebar') ? '3rem': '14rem' x: localStorage.getItem('slimSidebar') === 'true' ? '3rem' : '14rem'
} }
}).showToast() }).showToast()
if (id) { if (id) {

View File

@ -8,7 +8,7 @@ export function generatePath(el) {
throw new Error('No element passed to the generatePath function!') throw new Error('No element passed to the generatePath function!')
} }
let path = [el] const path = [el]
while ((el = el.parentNode) && el !== document) { while ((el = el.parentNode) && el !== document) {
path.push(el) path.push(el)
@ -18,14 +18,14 @@ export function generatePath(el) {
} }
export function isValidURL(text) { export function isValidURL(text) {
let lowerCaseText = text.toLowerCase() const lowerCaseText = text.toLowerCase()
if (lowerCaseText.startsWith('http')) { if (lowerCaseText.startsWith('http')) {
if ( if (
lowerCaseText.indexOf('deezer.com') >= 0 || lowerCaseText.includes('deezer.com') ||
lowerCaseText.indexOf('deezer.page.link') >= 0 || lowerCaseText.includes('deezer.page.link') ||
lowerCaseText.indexOf('open.spotify.com') >= 0 || lowerCaseText.includes('open.spotify.com') ||
lowerCaseText.indexOf('link.tospotify.com') >= 0 lowerCaseText.includes('link.tospotify.com')
) { ) {
return true return true
} }
@ -63,15 +63,15 @@ export function numberWithDots(x) {
// On scroll event, returns currentTarget = null // On scroll event, returns currentTarget = null
// Probably on other events too // Probably on other events too
export function debounce(func, wait, immediate) { export function debounce(func, wait, immediate) {
var timeout let timeout
return function() { return function () {
var context = this const context = this
var args = arguments const args = arguments
var later = function() { const later = function () {
timeout = null timeout = null
if (!immediate) func.apply(context, args) if (!immediate) func.apply(context, args)
} }
var callNow = immediate && !timeout const callNow = immediate && !timeout
clearTimeout(timeout) clearTimeout(timeout)
timeout = setTimeout(later, wait) timeout = setTimeout(later, wait)
if (callNow) func.apply(context, args) if (callNow) func.apply(context, args)
@ -104,10 +104,10 @@ export function copyToClipboard(text) {
export function getPropertyWithFallback(obj, ...props) { export function getPropertyWithFallback(obj, ...props) {
for (const prop of props) { for (const prop of props) {
// Example: this.is.an.example // Example: this.is.an.example
let hasDotNotation = /\./.test(prop) const hasDotNotation = /\./.test(prop)
// Searching the properties in the object // Searching the properties in the object
let valueToTest = hasDotNotation const valueToTest = hasDotNotation
? prop.split('.').reduce((o, i) => { ? prop.split('.').reduce((o, i) => {
if (o) { if (o) {
return o[i] return o[i]
@ -115,7 +115,7 @@ export function getPropertyWithFallback(obj, ...props) {
}, obj) }, obj)
: obj[prop] : obj[prop]
if ('undefined' !== typeof valueToTest) { if (typeof valueToTest !== 'undefined') {
return valueToTest return valueToTest
} }
} }