Merge branch 'main' into 'igorruckert-main-patch-30619'

# Conflicts:
#   src/lang/pt-br.js
This commit is contained in:
Igor Ruckert 2021-12-30 00:19:02 +00:00
commit 95b1833c97
16 changed files with 1160 additions and 1063 deletions

View File

@ -1,6 +1,6 @@
{
"name": "deemix-webui",
"version": "1.8.7",
"version": "1.8.10",
"scripts": {
"clean": "rimraf public/js/bundle.js public/js/bundle.temp.js public/js/bundle.js.map",
"clean-temp": "rimraf public/js/bundle.temp.js",

File diff suppressed because one or more lines are too long

View File

@ -26,8 +26,7 @@
</i>
<span
:class="{ hidden: isSlim }"
class="ml-5 overflow-hidden capitalize whitespace-no-wrap main-tablinks-text"
style="letter-spacing: 1.3px"
class="ml-3 overflow-hidden capitalize whitespace-no-wrap main-tablinks-text"
>
{{ $t(link.label) }}
</span>

View File

@ -254,7 +254,7 @@ export default {
},
updateQueue(update) {
// 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, stack } = update
if (uuid && this.queue.includes(uuid)) {
if (downloaded) {
@ -263,7 +263,7 @@ export default {
if (failed) {
this.queueList[uuid].failed++
this.queueList[uuid].errors.push({ message: error, data, errid })
this.queueList[uuid].errors.push({ message: error, data, errid, stack })
}
if (progress) {

View File

@ -26,7 +26,7 @@
<li v-html="$t('about.thanks')"></li>
<i18n path="about.upToDate.text" tag="li">
<template #newsChannel>
<a href="https://t.me/RemixDevNews" target="_blank">{{ $t('about.upToDate.newsChannel') }}</a>
<a href="https://tg.deemix.app" target="_blank">{{ $t('about.upToDate.newsChannel') }}</a>
</template>
</i18n>
</ul>
@ -46,7 +46,10 @@
<a href="https://www.reddit.com/r/deemix" target="_blank">🤖 {{ $t('about.officialSubreddit') }}</a>
</li>
<li>
<a href="https://t.me/RemixDevNews" target="_blank">📰 {{ $t('about.newsChannel') }}</a>
<a href="https://tg.deemix.app" target="_blank">📰 {{ $t('about.newsChannel') }}</a>
</li>
<li>
<a href="https://t.me/RemixDevNews" target="_blank">💾 {{ $t('about.devlogChannel') }}</a>
</li>
</ul>
@ -118,10 +121,6 @@
<strong>PayPal:</strong>
<a href="https://paypal.me/RemixDev" target="_blank">PayPal.me/RemixDev</a>
</li>
<li>
<i class="ethereum" v-html="ethereum" />
<strong>Ethereum:</strong> 0x1d2aa67e671485CD4062289772B662e0A6Ff976c
</li>
</ul>
<h2>{{ $t('about.titles.license') }}</h2>

View File

@ -13,7 +13,7 @@
<td>{{ error.data.id }}</td>
<td>{{ error.data.artist }}</td>
<td>{{ error.data.title }}</td>
<td>{{ error.errid ? $t(`errors.ids.${error.errid}`) : error.message }}</td>
<td><span :title="error.stack">{{ error.errid ? $t(`errors.ids.${error.errid}`) : error.message }}</span></td>
</tr>
</table>
</div>

View File

@ -24,10 +24,10 @@
</button>
<div v-show="activeTab === 'playlist'">
<div v-if="playlists.length === 0">
<div v-if="(playlists.length + spotifyPlaylists.length) === 0">
<h1>{{ $t('favorites.noPlaylists') }}</h1>
</div>
<div v-if="playlists.length > 0 || spotifyPlaylists.length > 0" class="release-grid">
<div v-if="(playlists.length + spotifyPlaylists.length) > 0" class="release-grid">
<div v-for="release in playlists" :key="release.id" class="release">
<router-link :to="{ name: 'Playlist', params: { id: release.id } }" class="cursor-pointer" tag="div">
<CoverContainer :cover="release.picture_medium" :link="release.link" is-rounded @click.stop="addToQueue" />
@ -194,6 +194,7 @@ export default defineComponent({
favoriteSpotifyPlaylists,
favoritePlaylists,
favoriteTracks,
lovedTracksPlaylist,
isRefreshingFavorites,
refreshFavorites
} = useFavorites()
@ -217,6 +218,7 @@ export default defineComponent({
artists: favoriteArtists,
playlists: favoritePlaylists,
spotifyPlaylists: favoriteSpotifyPlaylists,
lovedTracks: lovedTracksPlaylist,
refreshFavorites,
isRefreshingFavorites
}
@ -236,9 +238,12 @@ export default defineComponent({
const toDownload = this.getActiveRelease()
if (this.activeTab === 'track') {
const lovedTracks = this.getLovedTracksPlaylist()
sendAddToQueue(lovedTracks.link)
if (this.lovedTracks){
sendAddToQueue(this.lovedTracks)
} else {
const lovedTracks = this.getLovedTracksPlaylist()
sendAddToQueue(lovedTracks.link)
}
} else {
sendAddToQueue(aggregateDownloadLinks(toDownload))
}
@ -255,6 +260,7 @@ export default defineComponent({
switch (tab) {
case 'playlist':
toDownload = this.playlists
toDownload += this.spotifyPlaylists
break
case 'album':
toDownload = this.albums
@ -289,6 +295,7 @@ export default defineComponent({
if (lovedTracks.length !== 0) {
return lovedTracks[0]
} else {
toast(this.$t('toasts.noLovedPlaylist'), 'warning', true)
throw new Error('No loved tracks playlist!')
}
}

View File

@ -132,7 +132,7 @@
<h3>{{ $t('linkAnalyzer.countries') }}</h3>
<p v-for="(country, i) in countries" :key="i">{{ country[0] }} - {{ country[1] }}</p>
</template>
<template v-else>
<template v-else-if="this.type === 'track'">
<h3>{{ $t('linkAnalyzer.noCountries') }}</h3>
</template>

View File

@ -2,85 +2,78 @@
<div class="fixed-footer">
<h1 class="mb-8 text-5xl">{{ $t('settings.title') }}</h1>
<div v-if="isLoggedIn" id="logged_in_info" ref="loggedInInfo">
<img
id="settings_picture"
ref="userpicture"
:src="pictureHref"
alt="Profile Picture"
class="w-32 h-32 rounded-full"
/>
<i18n path="settings.login.loggedIn" tag="p">
<template #username>
<strong id="settings_username" ref="username">{{ user.name || 'not logged' }}</strong>
</template>
</i18n>
<p>{{userLicense}} | {{user.country}}</p>
<button class="btn btn-primary" @click="logout">
{{ $t('settings.login.logout') }}
</button>
<select v-if="accounts.length > 1" id="family_account" v-model="accountNum" @change="changeAccount">
<option v-for="(account, i) in accounts" :key="account" :value="i.toString()">
{{ account.name }}
</option>
</select>
</div>
<div class="settings-group">
<h3 class="settings-group__header"><i class="material-icons">person</i>{{ $t('settings.login.title') }}</h3>
<div class="my-5 space-y-5">
<div class="flex items-center">
<input
id="login_input_arl"
ref="loginInput"
:value="arl"
autocomplete="off"
placeholder="ARL"
type="password"
/>
<button class="ml-2 btn btn-primary btn-only-icon" @click="copyARLtoClipboard">
<i class="material-icons">assignment</i>
<div v-if="isLoggedIn" id="logged_in_info" ref="loggedInInfo">
<img
id="settings_picture"
ref="userpicture"
:src="pictureHref"
alt="Profile Picture"
class="w-32 h-32 rounded-full"
/>
<div class="user_info">
<i18n path="settings.login.loggedIn" tag="p">
<template #username>
<strong id="settings_username" ref="username">{{ user.name || 'not logged' }}</strong>
</template>
</i18n>
<p>{{userLicense}} | {{user.country}}</p>
<button class="btn btn-primary mt-3" @click="logout">
{{ $t('settings.login.logout') }}
</button>
</div>
<RouterLink :to="{ name: 'ARL' }" class="block">
{{ $t('settings.login.arl.question') }}
</RouterLink>
<!--
Uncomment when implemented
<a v-if="clientMode" class="block" href="#" @click="appLogin">
{{ $t('settings.login.login') }}
</a>
-->
<button class="btn btn-primary" style="width: 100%" @click="loginButton">
{{ $t('settings.login.arl.update') }}
</button>
<select v-if="accounts.length > 1" id="family_account" v-model="accountNum" @change="changeAccount">
<option v-for="(account, i) in accounts" :key="account" :value="i.toString()">
{{ account.name }}
</option>
</select>
</div>
</div>
<div v-if="!isLoggedIn" class="settings-group">
<h3 class="settings-group__header">
<i class="material-icons">person</i>{{ $t('settings.loginWithCredentials.title') }}
</h3>
<div v-else>
<form ref="loginWithCredentialsForm" @submit.prevent="loginWithCredentials">
<label>
<span>{{ $t('settings.loginWithCredentials.email') }}</span>
<input type="text" name="email" placeholder="email@example.com" class="mb-6"/>
</label>
<label>
<span>{{ $t('settings.loginWithCredentials.password') }}</span>
<input type="password" name="password" placeholder="●●●●●●●●" class="mb-6"/>
</label>
<button class="btn btn-primary login-button" type="submit">{{ $t('settings.loginWithCredentials.login') }}</button>
</form>
</div>
<form ref="loginWithCredentialsForm" class="my-5 space-y-5" @submit.prevent="loginWithCredentials">
<label>
<span>{{ $t('settings.loginWithCredentials.email') }}</span>
<input type="text" name="email" />
</label>
<label>
<span>{{ $t('settings.loginWithCredentials.password') }}</span>
<input type="password" name="password" />
</label>
<BaseAccordion class="my-5 space-y-5">
<template #title>
<span>{{ $t('settings.login.arl.title') }}</span>
</template>
<div class="my-5 space-y-5">
<div class="flex items-center">
<input
id="login_input_arl"
ref="loginInput"
:value="arl"
autocomplete="off"
placeholder="ARL"
type="password"
/>
<button class="ml-2 btn btn-primary btn-only-icon" @click="copyARLtoClipboard">
<i class="material-icons">assignment</i>
</button>
</div>
<button class="btn btn-primary" type="submit">{{ $t('settings.loginWithCredentials.login') }}</button>
</form>
<RouterLink :to="{ name: 'ARL' }" class="block">
{{ $t('settings.login.arl.question') }}
</RouterLink>
<button class="btn btn-primary" style="width: 100%" @click="loginButton">
{{ $t('settings.login.arl.update') }}
</button>
</div>
</BaseAccordion>
</div>
<div class="settings-group">
@ -364,6 +357,10 @@
<input v-model="settings.tags.artist" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.artist') }}</span>
</label>
<label class="with-checkbox" v-if="settings.tags.multiArtistSeparator != 'default'">
<input v-model="settings.tags.artists" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.artists') }}</span>
</label>
<label class="with-checkbox">
<input v-model="settings.tags.album" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.album') }}</span>
@ -461,6 +458,9 @@
</label>
</div>
</div>
<p v-if="settings.tags.multiArtistSeparator != 'default' && !settings.tags.artists" style="opacity: 0.75; color: #ffcc22">
{{ $t('settings.tags.artistsWarning') }}
</p>
</BaseAccordion>
<BaseAccordion class="settings-group">
@ -506,6 +506,11 @@
<input v-model="settings.fallbackSearch" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.fallbackSearch') }}</span>
</label>
<label class="with-checkbox">
<input v-model="settings.fallbackISRC" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.fallbackISRC') }}</span>
</label>
</div>
<div class="settings-container__third settings-container__third--only-checkbox">
<label class="with-checkbox">
@ -517,6 +522,11 @@
<input v-model="settings.logSearched" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.logSearched') }}</span>
</label>
<label class="with-checkbox">
<input v-model="settings.feelingLucky" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.feelingLucky') }}</span>
</label>
</div>
<div class="settings-container__third settings-container__third--only-checkbox">
<label class="with-checkbox">
@ -579,6 +589,9 @@
<option value=";">{{ $t('settings.other.multiArtistSeparator.using', { separator: ';' }) }}</option>
<option value="; ">{{ $t('settings.other.multiArtistSeparator.using', { separator: '; ' }) }}</option>
</select>
<p v-if="settings.tags.multiArtistSeparator != 'default'" style="opacity: 0.75; color: #ffcc22">
{{ $t('settings.other.multiArtistSeparator.warning') }}
</p>
</div>
<label class="with-checkbox">
@ -1007,6 +1020,10 @@ export default {
const { email } = fromLoginForm('email')
const { password } = fromLoginForm('password')
if (!email || !password) return
toast(this.$t('toasts.loggingIn'), 'loading', false, 'login-toast')
const { accessToken, arl } = await postToServer('loginWithCredentials', {
email,
password,
@ -1015,6 +1032,7 @@ export default {
if (accessToken !== this.accessToken) this.dispatchAccessTocken({ accessToken })
if (arl) this.login(arl)
else toast(this.$t('toasts.loginFailed'), 'close', true, 'login-toast')
},
appLogin() {
window.api.send('applogin')
@ -1073,11 +1091,21 @@ export default {
<style lang="scss" scoped>
#logged_in_info {
display: flex;
align-items: center;
flex-direction: column;
justify-content: space-evenly;
height: 250px;
display: grid;
align-items: center;
flex-direction: column;
justify-content: center;
grid-template-columns: 128px auto;
grid-template-rows: auto auto;
}
#logged_in_info .user_info {
padding-left: 24px;
}
#family_account {
margin-top: 24px;
grid-column: 1 / span 2;
}
.locale-flag {
@ -1164,4 +1192,12 @@ export default {
margin-bottom: 0.5rem;
}
}
.login-button {
display: block;
margin-left: auto;
padding-left: 24px;
padding-right: 24px;
margin-top: 0px;
}
</style>

View File

@ -11,6 +11,13 @@ const de = {
toggle_download_tab_hint: 'Erweitern/Minimieren',
clean_queue_hint: 'Vollständige entfernen',
cancel_queue_hint: 'Alle abbrechen',
open_downloads_folder: 'Download Ordner öffnen',
cut: 'Ausschneiden',
copy: 'Kopieren',
copyLink: 'Link kopieren',
copyImageLink: 'Bildlink kopieren',
copyDeezerLink: 'Deezer Link kopieren',
paste: 'Einfügen',
listTabs: {
empty: '',
all: 'Alle',
@ -28,7 +35,10 @@ const de = {
spotifyPlaylist: 'Spotify Playlist | Spotify Playlists',
releaseDate: 'Veröffentlichungsdatum',
error: 'Fehler'
}
},
yes: 'Ja',
no: 'Nein',
empty: 'Leer'
},
about: {
appStatus: {
@ -68,8 +78,7 @@ const de = {
officialSubreddit: 'Offizieller Subreddit',
newsChannel: 'Neuigkeiten Kanal',
questions: {
text:
'Suche bei Fragen oder Problemen mit der App als erstes nach einer Lösung im {subreddit}. Wenn du dort nichts findest, kannst du einen Beitrag mit deinen Problem auf dem Subreddit verfassen.',
text: 'Suche bei Fragen oder Problemen mit der App als erstes nach einer Lösung im {subreddit}. Wenn du dort nichts findest, kannst du einen Beitrag mit deinen Problem auf dem Subreddit verfassen.',
subreddit: 'Subreddit'
},
beforeReporting:
@ -80,8 +89,7 @@ const de = {
dontOpenIssues:
'<strong>ERSTELLE KEINE</strong> Fehlermeldungen um Fragen zu stellen, es existiert ein Subreddit dafür.',
newUI: {
text:
'Wenn du Python fließend beherrschst, kannst du versuchen, mithilfe der Basisbibliothek 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, mithilfe der Basisbibliothek 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'
},
acceptFeatures:
@ -121,10 +129,13 @@ const de = {
notEncodedNoAlternative: 'Track noch nicht codiert und keine Alternative gefunden!',
wrongBitrate: 'Track mit gewünschter Bitrate nicht gefunden.',
wrongBitrateNoAlternative: 'Track mit gewünschter Bitrate nicht gefunden und keine Alternative gefunden!',
no360RA: 'Track ist nicht verfügbar in Reality Audio 360.',
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!!'
no360RA: 'Track ist nicht in Reality Audio 360 verfügbar.',
notAvailable: 'Track ist nicht verfügbar auf den Servern von Deezer!',
notAvailableNoAlternative: 'Track ist nicht auf den Servern von Deezer verfügbar, keine Alternativen gefunden!',
noSpaceLeft: 'Kein Speicherplatz auf dem Gerät!',
albumDoesntExists: 'Das Album des Tracks ist nicht vorhanden, konnte keine Informationen sammeln.',
wrongLicense: 'Dein Account kann die Spur nicht an der gewünschten Bitrate streamen.',
wrongGeolocation: 'Dein Account kann den Track nicht aus Deinem aktuellen Land streamen.'
}
},
favorites: {
@ -143,8 +154,7 @@ const de = {
}
},
linkAnalyzer: {
info:
'Diesen Abschnitt kannst du nutzen, um weitere Informationen über den gewünschten Link zu erhalten, den du herunterladen möchtest.',
info: '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',
@ -162,8 +172,12 @@ const de = {
label: 'Label',
recordType: 'Art der Aufnahme',
genres: 'Genres',
tracklist: 'Trackliste'
}
tracklist: 'Trackliste',
readable: 'Lesbar',
available: 'Verfügbar'
},
countries: 'Länder',
noCountries: 'Dieser Track ist in keinem Land verfügbar.'
},
search: {
startSearching: 'Suche starten!',
@ -183,7 +197,7 @@ const de = {
alreadyInQueue: '{item} ist bereits in der Warteschlange!',
finishDownload: '{item} vollständig heruntergeladen.',
allDownloaded: 'Alle Downloads abgeschlossen!',
refreshFavs: 'Abgeschlossene Downloads neu laden!',
refreshFavs: 'Abgeschlossene Downloads neuladen!',
loggingIn: 'Einloggen',
loggedIn: 'Eingeloggt',
alreadyLogged: 'Bereits eingeloggt',
@ -191,10 +205,14 @@ const de = {
loggedOut: 'Ausgeloggt',
cancellingCurrentItem: 'Aktuelle Auswahl abbrechen.',
currentItemCancelled: 'Aktuelle Auswahl wurde abgebrochen',
startAddingArtist: '{artist} Alben werden hinzugefügt',
finishAddingArtist: '{artist} Alben wurden hinzugefügt',
startAddingArtist: 'Alben von {artist} werden hinzugefügt',
finishAddingArtist: 'Alben von {artist} wurden hinzugefügt',
startConvertingSpotifyPlaylist: 'Konvertierern von Spotify-Tracks zu Deezer-Tracks',
finishConvertingSpotifyPlaylist: 'Spotify Playlist convertiert'
finishConvertingSpotifyPlaylist: 'Spotify Playlist convertiert',
loginNeededToDownload: 'Du musst eingeloggt sein, um Tracks herunterladen zu können!',
deezerNotAvailable: 'Deezer ist in deinem Land nicht verfügbar. Du solltest eine VPN nutzen.',
startGeneratingItems: 'Verarbeite {n} Artikeln....',
finishGeneratingItems: '{n} Items generiert.'
},
settings: {
title: 'Einstellungen',
@ -204,9 +222,10 @@ const de = {
loggedIn: 'Du bist eingeloggt als {username}',
arl: {
question: 'Wie bekomme ich meine eigene ARL?',
update: 'Update ARL'
update: 'ARL aktualisieren'
},
logout: 'Ausloggen'
logout: 'Ausloggen',
login: 'Über deezer.com einloggen'
},
loginWithCredentials: {
title: 'Mit Zugangsdaten einloggen',
@ -216,7 +235,10 @@ const de = {
},
appearance: {
title: 'Design',
slimDownloadTab: 'Schmaler Download-Tab'
slimDownloadTab: 'Schmaler Download-Tab',
slimSidebar: 'Schlanke Seitenleiste',
searchButton: 'Suchschaltfläche anzeigen',
bitrateTags: 'Qualitäts-Tag in Download-Warteschlange anzeigen'
},
downloadPath: {
title: 'Download Pfad'
@ -224,8 +246,11 @@ const de = {
templates: {
title: 'Vorlagen',
tracknameTemplate: 'Vorlage für den Tracknamen',
albumTracknameTemplate: 'Vorlage für Tracks in einem Album',
playlistTracknameTemplate: 'Vorlage für Tracks in einer Playlist'
tracknameAvailableVariables: 'Verfügbare Trackname Variablen',
albumTracknameTemplate: 'Album-Track-Vorlage.',
albumTracknameAvailableVariables: 'Verfügbare Album-Track-Variablen',
playlistTracknameTemplate: 'Vorlage für Tracks in einer Playlist',
playlistTracknameAvailableVariables: 'Verfügbare Playlist Trackvariablen'
},
folders: {
title: 'Ordner',
@ -259,7 +284,8 @@ const de = {
y: 'Ja überschreibe die Dateien',
n: 'Nein überschreibe die Dateien nicht',
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',
e: 'Nein, und schau nicht auf die Erweiterungen'
},
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',
@ -284,7 +310,11 @@ const de = {
png: 'Ein png Bild',
both: 'Beides (jpg + png)'
},
jpegImageQuality: 'JPEG Qualität'
jpegImageQuality: 'JPEG Qualität',
embeddedArtworkPNG: 'Eingebettete Grafiken als PNG speichern',
embeddedPNGWarning: 'PNGs werden von Deezer nicht offiziell unterstützt und können fehlerhaft sein',
imageSizeWarning: 'Alles über x1200 wird nicht offiziell von Deezer verwendet, es können Probleme auftreten',
coverDescriptionUTF8: 'Cover-Beschreibung mit UTF8 speichern (iTunes Cover Fix)'
},
tags: {
head: 'Welche Tags sollen gespeichert werden?',
@ -308,9 +338,11 @@ const de = {
replayGain: 'Wiedergabe Lautstärke',
label: 'Album Plattenlabel',
lyrics: 'Nicht synchronisierte Texte',
syncedLyrics: 'Synchronisierte Texte',
copyright: 'Copyright',
composer: 'Komponist',
involvedPeople: 'Mitwirkende Personen'
involvedPeople: 'Mitwirkende Personen',
source: 'Quelle und Song ID'
},
other: {
title: 'Sonstige',
@ -360,14 +392,21 @@ const de = {
title: 'Spotify Features',
clientID: 'Spotify Client ID',
clientSecret: 'Spotify Client Secret',
username: 'Spotify Benutzername'
username: 'Spotify Benutzername',
question: 'Wie aktiviere ich die Spotify Features?'
},
reset: 'Auf Standardwerte zurücksetzen',
resetMessage: 'Bist du sicher, dass du zu den Standarteinstellungen zurückkehren willst?',
save: 'Speichern',
toasts: {
init: 'Einstellungen geladen!',
update: 'Einstellungen aktualisiert!',
reset: 'Einstellungen auf den Standart zurückgesetzt!',
ARLcopied: 'ARL wurde in die Zwischenablage kopiert'
},
logs: {
title: 'Logs',
areLogsActive: 'Aktiv'
}
},
sidebar: {
@ -380,7 +419,11 @@ const de = {
about: 'Info'
},
tracklist: {
downloadSelection: 'Downloads'
downloadSelection: 'Herunterladen'
},
logs: {
event: 'Event',
data: 'Daten'
}
}

View File

@ -81,6 +81,7 @@ const en = {
officialWebuiRepo: 'Official WebUI Repository',
officialSubreddit: 'Official Subreddit',
newsChannel: 'News Channel',
devlogChannel: 'Devlog Channel',
questions: {
text: `If you have questions or problems with the app, search for a solution on the {subreddit} first. Then, if you don't find anything you can make a post with your issue on the subreddit.`,
subreddit: 'subreddit'
@ -133,7 +134,9 @@ const en = {
noSpaceLeft: 'No space left on the device!',
albumDoesntExists: "Track's album doesn't exist, failed to gather info.",
wrongLicense: "Your account can't stream the track at the desired bitrate.",
wrongGeolocation: "Your account can't stream the track from your current country."
wrongGeolocation: "Your account can't stream the track from your current country.",
wrongGeolocationNoAlternative:
"Your account can't stream the track from your current country and no alternative found."
}
},
favorites: {
@ -212,7 +215,8 @@ const en = {
loginNeededToDownload: 'You need to log in to download tracks!',
deezerNotAvailable: 'Deezer is not available in your country. You should use a VPN.',
startGeneratingItems: 'Processing {n} items...',
finishGeneratingItems: 'Generated {n} items.'
finishGeneratingItems: 'Generated {n} items.',
noLovedPlaylist: 'No loved tracks playlist!'
},
settings: {
title: 'Settings',
@ -221,6 +225,7 @@ const en = {
title: 'Login',
loggedIn: 'You are logged in as {username}',
arl: {
title: 'Use ARL instead',
question: 'How do I get my own ARL?',
update: 'Update ARL'
},
@ -289,6 +294,8 @@ const en = {
},
fallbackBitrate: 'Bitrate fallback',
fallbackSearch: 'Search fallback',
fallbackISRC: 'Fallback with ISRC search',
feelingLucky: 'Gamble with CDNs and caches',
logErrors: 'Create log files for errors',
logSearched: 'Create log files for searched tracks',
createM3U8File: 'Create playlist file',
@ -320,6 +327,7 @@ const en = {
head: 'Which tags to save',
title: 'Title',
artist: 'Artist',
artists: 'Extra ARTISTS tag',
album: 'Album',
cover: 'Cover',
trackNumber: 'Track Number',
@ -342,7 +350,9 @@ const en = {
copyright: 'Copyright',
composer: 'Composer',
involvedPeople: 'Involved People',
source: 'Source and song ID'
source: 'Source and song ID',
artistsWarning:
"Disabling the ARTISTS tag while not using standard specification won't preserve multiartist support"
},
other: {
title: 'Other',
@ -354,7 +364,9 @@ const en = {
nothing: 'Save only the main artist',
default: 'Using standard specification',
andFeat: 'Using & and feat.',
using: 'Using "{separator}"'
using: 'Using "{separator}"',
warning:
'Using any separator other than the standard specification will add a extra ARTISTS tag to preserve multiartist support'
},
singleAlbumArtist: 'Save only the main album artist',
albumVariousArtists: 'Keep "Various Artists" in the Album Artists',

View File

@ -52,11 +52,11 @@ const fr = {
offline: 'app hors ligne'
},
updates: {
currentVersion: 'Version Actuelle',
currentVersion: 'Version Actuelle Du Logiciel',
currentWebuiVersion: 'Version Actuelle De La WebUI',
versionNotAvailable: 'N/A',
updateAvailable: "Vous n'utilisez pas la dernière version disponible : {version}",
deemixVersion: 'Version de la bibliothèque deemix'
deemixVersion: 'Version Actuelle De La Bibliothèque deemix'
},
titles: {
usefulLinks: 'Liens Utiles',
@ -83,6 +83,7 @@ const fr = {
officialWebuiRepo: 'Répertoire De Dépôt Officiel De La WebUI',
officialSubreddit: 'Subreddit Officiel',
newsChannel: "Canal d'Informations",
devlogChannel: 'Canal De Développement',
questions: {
text: `Si vous avez des questions ou des problèmes avec l'application, cherchez d'abord une solution dans le {subreddit}. Ensuite, si la solution ne s'y trouve pas, vous pouvez publier un message dans le subreddit en décrivant votre problème.`,
subreddit: 'subreddit'
@ -143,12 +144,14 @@ const fr = {
noSpaceLeft: "L'espace disponible sur cet appareil est insuffisant !",
albumDoesntExists: "Aucun album n'existe pour cette piste, impossible de collecter les informations nécessaires.",
wrongLicense: 'Votre compte ne prend pas en charge la piste au débit souhaité.',
wrongGeolocation: 'Votre compte ne prend pas en charge la piste depuis votre pays actuel.'
wrongGeolocation: 'Votre compte ne prend pas en charge la piste depuis votre pays actuel.',
wrongGeolocationNoAlternative:
"Votre compte ne prend pas en charge la piste depuis votre pays actuel et aucune alternative n'a été trouvée."
}
},
favorites: {
title: 'Favoris',
noPlaylists: "Aucune Playlist n'a été trouvée",
noPlaylists: "Aucune Playlist Favorite n'a été trouvée",
noAlbums: "Aucun Album Favori n'a été trouvé",
noArtists: "Aucun Artiste Favori n'a été trouvé",
noTracks: "Aucune Piste Favorite n'a été trouvée"
@ -232,6 +235,7 @@ const fr = {
title: 'Connexion',
loggedIn: 'Vous êtes connecté en tant que {username}',
arl: {
title: 'Utiliser de préférence la connexion via ARL',
question: 'Comment obtenir mon ARL personnel ?',
update: "Actualiser l'ARL"
},
@ -300,7 +304,9 @@ const fr = {
e: "Non, et ne pas tenir compte de l'extension du fichier"
},
fallbackBitrate: "Recourir à un débit plus faible si le débit préféré n'est pas disponible",
fallbackSearch: "Rechercher la piste si le lien original n'est pas disponible",
fallbackSearch: "Rechercher la piste ailleurs si le lien original n'est pas disponible",
fallbackISRC: "Rechercher la piste à l'aide de son ISRC si le lien original n'est pas disponible",
feelingLucky: "Utiliser les CDNs et les caches (ancienne méthode de téléchargement des pistes)",
logErrors: "Créer un fichier journal d'erreurs",
logSearched: 'Créer un fichier journal des pistes recherchées',
createM3U8File: 'Créer un fichier de playlist',
@ -334,6 +340,7 @@ const fr = {
head: 'Métadonnées à sauvegarder',
title: 'Titre',
artist: 'Artiste',
artists: 'Métadonnée supplémentaire ARTISTS',
album: 'Album',
cover: 'Pochette',
trackNumber: 'Numéro De Piste',
@ -356,7 +363,9 @@ const fr = {
copyright: "Droits d'Auteur (Copyright)",
composer: 'Compositeur',
involvedPeople: 'Personnes Impliquées',
source: 'ID de la source et de la piste'
source: 'ID de la source et de la piste',
artistsWarning:
"La désactivation de la métadonnée ARTISTS sans utiliser la spécification standard ne préservera pas le support multi-artiste."
},
other: {
title: 'Autre',
@ -368,7 +377,9 @@ const fr = {
nothing: "Enregistrer uniquement l'artiste principal",
default: 'En utilisant la spécification standard',
andFeat: 'En utilisant & et feat.',
using: 'En utilisant "{separator}"'
using: 'En utilisant "{separator}"',
warning:
"L'utilisation d'un séparateur autre que la spécification standard nécessitera l'ajout d'une métadonnée ARTISTS afin de préserver le support multi-artiste."
},
singleAlbumArtist: "Enregistrer uniquement l'artiste principal de l'album",
albumVariousArtists: `Conserver "Various Artists" dans les Artistes de l'Album`,

View File

@ -82,6 +82,7 @@ const it = {
officialWebuiRepo: `Repository Ufficiale dell'Interfaccia Web`,
officialSubreddit: 'Subreddit Ufficiale',
newsChannel: 'Canale delle news',
devlogChannel: 'Canale Devlog',
questions: {
text: `Se dovessi avere domande o problemi con l'app, cerca prima una soluzione nel {subreddit}. Se non trovi nulla, puoi postare li il tuo problema.`,
subreddit: 'subreddit ufficiale'

View File

@ -1,11 +1,11 @@
const ko = {
globals: {
welcome: '잘왔다, deemix에',
welcome: 'Deemix에 오신 것을 환영합니다',
back: '뒤로',
loading: '불러오는 중',
download: '{thing} 다운로드',
by: 'by {artist}',
in: 'in {album}',
by: '- {artist}',
in: '{album}',
download_hint: '다운로드',
play_hint: '재생',
toggle_download_tab_hint: '펼치기/접기',
@ -52,7 +52,7 @@ const ko = {
currentVersion: '현재 버전',
currentWebuiVersion: '현재 WebUI 버전',
versionNotAvailable: 'N/A',
updateAvailable: `최신버전으로 업데이트 할 수 있습니다: {version}`,
updateAvailable: `최신 버전 ({version})으로 업데이트 할 수 있습니다`,
deemixVersion: 'deemix lib 버전'
},
titles: {
@ -169,7 +169,7 @@ const ko = {
}
},
search: {
startSearching: '검색을 해보세요!',
startSearching: '검색세요!',
description: '트랙, 아티스트, 재생목록, Deezer 링크 등으로 검색할 수 있습니다!',
fans: '{n}명의 팬들',
@ -180,7 +180,7 @@ const ko = {
noResultsPlaylist: '발견된 재생목록 없음'
},
searchbar: '원하는 것을 검색하세요 (링크를 붙여넣을 수도 있습니다)',
downloads: '다운로드',
downloads: '다운로드',
toasts: {
restoringQueue: '다운로드 대기 열 복원중...',
queueRestored: '다운로드 대기 열이 복원되었습니다!',
@ -204,7 +204,7 @@ const ko = {
loginNeededToDownload: '트랙을 다운로드하려면 로그인이 필요합니다!',
deezerNotAvailable: 'Deezer 사이트는 현재 귀하의 국가에서 사용이 불가능합니다. VPN을 사용하세요.',
startGeneratingItems: '{n}개의 항목 진행중...',
finishGeneratingItems: '{n}개의 항목 생성.'
finishGeneratingItems: '{n}개의 항목 생성되었습니다.'
},
settings: {
title: '설정',
@ -264,12 +264,12 @@ const ko = {
1: 'MP3 128kbps'
},
overwriteFile: {
title: '파일을 덮어쓸까요?',
y: '네, 파일을 덮어쓰세요',
n: '아뇨, 파일을 덮어쓰지 마세요',
t: '태그만 덮어쓰세요',
b: '아뇨, 양쪽 다 놔두고 중복되는 파일에 번호를 추가하세요',
e: '아뇨, 확장명을 변경하세요'
title: '파일 덮어쓰기 여부',
y: '파일 덮어쓰기',
n: '파일 덮어쓰지 않기',
t: '태그만 덮어쓰',
b: '모두 유지한 뒤 새 파일에 번호 넣기',
e: '확장자 변경하기'
},
fallbackBitrate: '비트레이트 대비책',
fallbackSearch: '검색 대비책',
@ -289,10 +289,10 @@ const ko = {
localArtworkSize: '외부 저장 그림 크기',
embeddedArtworkSize: '내부 저장 그림 크기',
localArtworkFormat: {
title: '별도로 저장할 그림의 형식을 무엇으로 하시겠습니까?',
title: '별도로 저장할 그림의 형식',
jpg: 'jpeg 이미지',
png: 'png 이미지',
both: 'jpeg와 png 둘 다'
both: 'jpeg와 png 모두'
},
jpegImageQuality: 'JPEG 이미지 품질',
embeddedArtworkPNG: '포함된 그림의 형식을 PNG로 저장합니다',
@ -376,7 +376,7 @@ const ko = {
title: '스포티파이 기능',
clientID: 'Spotify ClientID',
clientSecret: 'Spotify Client Secret',
username: 'Spotify 사용자이름',
username: 'Spotify 사용자 이름',
question: '스포티파이 기능들을 사용하려면 어떻게 해야 합니까?'
},
reset: '기본 설정으로 초기화',

View File

@ -9,12 +9,13 @@ const favoriteAlbums = ref([])
const favoriteSpotifyPlaylists = ref([])
const favoritePlaylists = ref([])
const favoriteTracks = ref([])
const lovedTracksPlaylist = ref('')
const isLoggedWithSpotify = computed(() => store.getters.isLoggedWithSpotify)
const isRefreshingFavorites = ref(false)
const setAllFavorites = data => {
const { tracks, albums, artists, playlists } = data
const { tracks, albums, artists, playlists, lovedTracks } = data
isRefreshingFavorites.value = false
@ -22,6 +23,7 @@ const setAllFavorites = data => {
favoriteAlbums.value = albums
favoritePlaylists.value = playlists
favoriteTracks.value = tracks
lovedTracksPlaylist.value = lovedTracks
}
const setSpotifyPlaylists = response => {
@ -59,6 +61,7 @@ export const useFavorites = () => ({
favoriteSpotifyPlaylists,
favoritePlaylists,
favoriteTracks,
lovedTracksPlaylist,
isRefreshingFavorites,
refreshFavorites
})

1740
yarn.lock

File diff suppressed because it is too large Load Diff