stuff
19
Dockerfile
Normal file
@ -0,0 +1,19 @@
|
||||
FROM debian:11-slim
|
||||
|
||||
# set work dir
|
||||
WORKDIR /root/
|
||||
|
||||
# Initial update repo and upgrade packges # Make dir for freezer app files
|
||||
|
||||
RUN apt update \
|
||||
&& apt upgrade -y \
|
||||
&& apt install nodejs -y --no-install-recommends \
|
||||
&& apt auto-remove -y \
|
||||
&& apt clean -y \
|
||||
&& mkdir /root/freezer/
|
||||
|
||||
# Copy files to freezer app dir
|
||||
COPY buildfiles/ /root/freezer/
|
||||
|
||||
# Start service
|
||||
CMD ["/usr/bin/node", "/root/freezer/app/main.js"]
|
76
buildfiles/README.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Freezer
|
||||
|
||||
Free music streaming client for Deezer based on the Deezloader/Deemix "bug".
|
||||
|
||||
## Downloads
|
||||
|
||||
Binaries are available in:
|
||||
|
||||
[Telegram channel](https://t.me/freezereleases)
|
||||
[Website](https://www.freezer.life/)
|
||||
|
||||
## Links
|
||||
|
||||
Join group: https://t.me/freezerpc
|
||||
Discord: https://discord.gg/7ap654Tp3z
|
||||
|
||||
## Building
|
||||
|
||||
Requirements: NodeJS 12+
|
||||
|
||||
You can build binary using npm script:
|
||||
```
|
||||
npm i
|
||||
npm run build
|
||||
```
|
||||
|
||||
Or manually:
|
||||
|
||||
```
|
||||
npm i
|
||||
cd app
|
||||
npm i
|
||||
```
|
||||
|
||||
Frontend:
|
||||
|
||||
```
|
||||
cd client
|
||||
npm i
|
||||
npm run build
|
||||
cd ../..
|
||||
```
|
||||
|
||||
Then you can run server-only using, default port: `10069`:
|
||||
|
||||
```
|
||||
cd app
|
||||
node main.js
|
||||
```
|
||||
|
||||
You can build binaries using:
|
||||
|
||||
```
|
||||
npm run dist
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
**Francesco** - design help, tester
|
||||
**Xandar** - Community manager, helper, tester
|
||||
**Bas Curtiz** - logo
|
||||
**RemixDev** - how2deez
|
||||
|
||||
**Huge thanks to all the Crowdin translators and all the contributors to this project <3**
|
||||
|
||||
## Support me
|
||||
BTC: `14hcr4PGbgqeXd3SoXY9QyJFNpyurgrL9y`
|
||||
ETH: `0xb4D1893195404E1F4b45e5BDA77F202Ac4012288`
|
||||
|
||||
## Disclaimer
|
||||
|
||||
```
|
||||
Freezer was not developed for piracy, but educational and private usage.
|
||||
It may be illegal to use this in your country!
|
||||
I am not responsible in any way for the usage of this app.
|
||||
```
|
15
buildfiles/app/.eslintrc.js
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"node": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 12
|
||||
},
|
||||
"rules": {
|
||||
"allowEmptyCatch": 0
|
||||
}
|
||||
};
|
BIN
buildfiles/app/assets/icon-taskbar-black.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
buildfiles/app/assets/icon-taskbar-white.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
buildfiles/app/assets/icon-taskbar.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
buildfiles/app/assets/icon.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
buildfiles/app/assets/pause.png
Normal file
After Width: | Height: | Size: 370 B |
BIN
buildfiles/app/assets/play.png
Normal file
After Width: | Height: | Size: 552 B |
BIN
buildfiles/app/assets/skip-next.png
Normal file
After Width: | Height: | Size: 479 B |
BIN
buildfiles/app/assets/skip-previous.png
Normal file
After Width: | Height: | Size: 524 B |
364
buildfiles/app/background.js
Normal file
@ -0,0 +1,364 @@
|
||||
const {app, BrowserWindow, ipcMain, Tray, Menu, session, dialog, shell, nativeTheme} = require('electron');
|
||||
const {createServer} = require('./src/server');
|
||||
const path = require('path');
|
||||
const arg = require('arg');
|
||||
const { exit } = require('process');
|
||||
const packageJson = require('./package.json');
|
||||
const chalk = require('chalk');
|
||||
const {Settings} = require('./src/settings');
|
||||
const fs = require('fs');
|
||||
|
||||
let win;
|
||||
let tray;
|
||||
let settings;
|
||||
|
||||
let shouldExit = false;
|
||||
let playing = false;
|
||||
|
||||
//Arguments
|
||||
const args = arg({
|
||||
'--server': Boolean,
|
||||
'--host': String,
|
||||
'--port': Number,
|
||||
'--help': Boolean,
|
||||
'--settings': Boolean,
|
||||
'--reset-settings': Boolean,
|
||||
'--reset-downloads': Boolean,
|
||||
'--log': Boolean,
|
||||
|
||||
'-S': '--server',
|
||||
'-H': '--host',
|
||||
'-h': '--help',
|
||||
'-p': '--port'
|
||||
}, {argv: process.argv.slice(1)});
|
||||
|
||||
executeCli();
|
||||
|
||||
//Get path to asset
|
||||
function assetPath(a) {
|
||||
return path.join(__dirname, 'assets', a);
|
||||
}
|
||||
|
||||
//Execute actions by parameters
|
||||
function executeCli() {
|
||||
if (args['--help']) {
|
||||
console.log(`
|
||||
${chalk.bold.blue('Freezer PC')} ${chalk.bold(`v${packageJson.version}`)} by exttex
|
||||
|
||||
${chalk.bold('USAGE:')}
|
||||
--help, -h Prints this and exits
|
||||
--server, -S Starts in server mode
|
||||
--host, -H Override host (default: 127.0.0.1)
|
||||
--port, -p Override port (default: 10069)
|
||||
|
||||
${chalk.bold('TOOLS:')}
|
||||
--settings Prints current settings and exits
|
||||
--log Prints server log and exits
|
||||
--reset-settings Reset settings to default
|
||||
--reset-downloads Delete downloads cache and database
|
||||
`);
|
||||
exit(0);
|
||||
}
|
||||
//Print settings and exit
|
||||
if (args["--settings"]) {
|
||||
let settings = new Settings();
|
||||
settings.load();
|
||||
console.log(JSON.stringify(settings, null, 2));
|
||||
exit(0);
|
||||
}
|
||||
if (args["--reset-settings"]) {
|
||||
fs.unlinkSync(Settings.getPath());
|
||||
exit(0);
|
||||
}
|
||||
//Delete downloads db and temp
|
||||
if (args['--reset-downloads']) {
|
||||
fs.unlinkSync(Settings.getDownloadsDB());
|
||||
fs.rmdirSync(Settings.getTempDownloads(), {recursive: true});
|
||||
exit(0);
|
||||
}
|
||||
//Show log
|
||||
if (args['--log']) {
|
||||
let p = path.join(Settings.getDir(), "freezer-server.log");
|
||||
console.log(fs.readFileSync(p, {encoding: 'utf-8'}).toString());
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
async function startServer() {
|
||||
|
||||
//Override settings
|
||||
let override = {};
|
||||
if (args["--host"])
|
||||
override['host'] = args["--host"];
|
||||
if (args["--port"])
|
||||
override['port'] = args["--port"];
|
||||
|
||||
settings = await createServer(true, () => {
|
||||
//Server error
|
||||
shouldExit = true;
|
||||
if (win) win.close();
|
||||
|
||||
dialog.showMessageBoxSync({
|
||||
type: 'error',
|
||||
title: 'Server error',
|
||||
message: 'Server error occured, Freezer is probably already running!',
|
||||
buttons: ['Close']
|
||||
});
|
||||
}, override);
|
||||
}
|
||||
|
||||
async function createWindow() {
|
||||
//Create window
|
||||
win = new BrowserWindow({
|
||||
width: settings.width,
|
||||
darkTheme: true,
|
||||
height: settings.height,
|
||||
minWidth: 620,
|
||||
minHeight: 600,
|
||||
resizable: true,
|
||||
autoHideMenuBar: true,
|
||||
frame: false,
|
||||
icon: assetPath("icon.png"),
|
||||
title: 'Freezer',
|
||||
webPreferences: {
|
||||
enableRemoteModule: true,
|
||||
nodeIntegration: true,
|
||||
devTools: true
|
||||
}
|
||||
});
|
||||
|
||||
win.loadURL(`http://localhost:${settings.port}`);
|
||||
|
||||
//Minimize to tray
|
||||
win.on('minimize', (event) => {
|
||||
if (settings.minimizeToTray) {
|
||||
event.preventDefault();
|
||||
win.hide();
|
||||
}
|
||||
});
|
||||
|
||||
//On close
|
||||
win.on('close', async (event) => {
|
||||
if (shouldExit) {
|
||||
win = null;
|
||||
tray = null;
|
||||
app.quit();
|
||||
return true;
|
||||
}
|
||||
|
||||
//Normal exit
|
||||
if (!settings || !settings.arl || settings.arl == '' || settings.closeOnExit) {
|
||||
win.webContents.send('onExit');
|
||||
shouldExit = true;
|
||||
}
|
||||
event.preventDefault();
|
||||
win.hide();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Thumbnail Toolbars
|
||||
setThumbarButtons();
|
||||
}
|
||||
|
||||
//Single instance
|
||||
const singleInstanceLock = app.requestSingleInstanceLock();
|
||||
if (!singleInstanceLock) {
|
||||
app.quit();
|
||||
} else {
|
||||
app.on('second-instance', () => {
|
||||
if (win) {
|
||||
if (!win.visible) win.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Create window
|
||||
app.on('ready', async () => {
|
||||
await startServer();
|
||||
//Server mode
|
||||
if (args['--server']) return;
|
||||
createWindow();
|
||||
|
||||
//Create Tray
|
||||
if (settings.forceWhiteTrayIcon || nativeTheme.shouldUseDarkColors)
|
||||
tray = new Tray(assetPath("icon-taskbar-white.png"));
|
||||
else
|
||||
tray = new Tray(assetPath("icon-taskbar-black.png"));
|
||||
tray.on('double-click', () => restoreWindow());
|
||||
tray.on('click', () => restoreWindow());
|
||||
|
||||
setTray();
|
||||
});
|
||||
|
||||
//Restore or create new window
|
||||
function restoreWindow() {
|
||||
if (win) {
|
||||
win.show();
|
||||
setThumbarButtons();
|
||||
return;
|
||||
}
|
||||
createWindow();
|
||||
}
|
||||
|
||||
//Update tray context menu
|
||||
function setTray() {
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: 'Restore',
|
||||
type: 'normal',
|
||||
click: () => restoreWindow()
|
||||
},
|
||||
playing ?
|
||||
{
|
||||
label: 'Pause',
|
||||
type: 'normal',
|
||||
click: () => win.webContents.send('togglePlayback')
|
||||
}
|
||||
: {
|
||||
label: 'Play',
|
||||
type: 'normal',
|
||||
click: () => win.webContents.send('togglePlayback')
|
||||
},
|
||||
{
|
||||
label: 'Next',
|
||||
type: 'normal',
|
||||
click: () => win.webContents.send('skipNext')
|
||||
},
|
||||
{
|
||||
label: 'Previous',
|
||||
type: 'normal',
|
||||
click: () => win.webContents.send('skipPrev')
|
||||
},
|
||||
{
|
||||
label: 'Exit',
|
||||
type: 'normal',
|
||||
click: () => {
|
||||
shouldExit = true;
|
||||
if (!win) return app.quit();
|
||||
win.close();
|
||||
}
|
||||
}
|
||||
]);
|
||||
tray.setContextMenu(contextMenu);
|
||||
}
|
||||
|
||||
//Update Thumbnail Toolbars (Windows)
|
||||
function setThumbarButtons() {
|
||||
win.setThumbarButtons([
|
||||
{
|
||||
tooltip: 'Skip Previous',
|
||||
icon: assetPath('skip-previous.png'),
|
||||
click: () => win.webContents.send('skipPrev')
|
||||
},
|
||||
//Play/Pause
|
||||
playing ?
|
||||
{
|
||||
tooltip: 'Pause',
|
||||
icon: assetPath('pause.png'),
|
||||
click: () => win.webContents.send('togglePlayback')
|
||||
} :
|
||||
{
|
||||
tooltip: 'Play',
|
||||
icon: assetPath('play.png'),
|
||||
click: () => win.webContents.send('togglePlayback')
|
||||
},
|
||||
//Skip next
|
||||
{
|
||||
tooltip: 'Skip Next',
|
||||
icon: assetPath('skip-next.png'),
|
||||
click: () => win.webContents.send('skipNext')
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
//[] button
|
||||
ipcMain.on('maximize', () => {
|
||||
win.isMaximized() ? win.unmaximize() : win.maximize();
|
||||
});
|
||||
|
||||
//_ button in ui
|
||||
ipcMain.on('minimize', () => {
|
||||
win.minimize();
|
||||
});
|
||||
|
||||
//X button in ui
|
||||
ipcMain.on('close', () => {
|
||||
win.close();
|
||||
});
|
||||
|
||||
ipcMain.on('openUrl', (event, args) => {
|
||||
shell.openExternal(args);
|
||||
});
|
||||
|
||||
//Playing state change from UI
|
||||
ipcMain.on('playing', (event, args) => {
|
||||
playing = args;
|
||||
setThumbarButtons();
|
||||
setTray();
|
||||
});
|
||||
|
||||
//Update settings from ui
|
||||
ipcMain.on('updateSettings', (event, args) => {
|
||||
Object.assign(settings, args);
|
||||
});
|
||||
|
||||
//onExit callback
|
||||
ipcMain.on('onExit', () => {
|
||||
shouldExit = true;
|
||||
win.close();
|
||||
});
|
||||
|
||||
//Open downloads directory
|
||||
ipcMain.on('openDownloadsDir', async () => {
|
||||
if ((await shell.openPath(settings.downloadsPath)) == "") return;
|
||||
shell.showItemInFolder(settings.downloadsPath);
|
||||
});
|
||||
|
||||
//Download path picker
|
||||
ipcMain.on('selectDownloadPath', async (event) => {
|
||||
let res = await dialog.showOpenDialog({
|
||||
title: 'Downloads folder',
|
||||
properties: ['openDirectory', 'promptToCreate'],
|
||||
});
|
||||
if (!res.canceled && res.filePaths.length > 0) {
|
||||
event.reply('selectDownloadPath', res.filePaths[0]);
|
||||
}
|
||||
});
|
||||
|
||||
//Login using browser
|
||||
ipcMain.on('browserLogin', async (event) => {
|
||||
//Initial clean
|
||||
session.defaultSession.clearStorageData();
|
||||
|
||||
let lwin = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
icon: assetPath('icon.png'),
|
||||
title: "Deezer Login",
|
||||
resizable: true,
|
||||
autoHideMenuBar: true,
|
||||
webPreferences: {
|
||||
nodeIntegration: false
|
||||
}
|
||||
});
|
||||
lwin.loadURL('https://deezer.com/login');
|
||||
|
||||
let arl = await new Promise((res) => {
|
||||
lwin.webContents.on('did-navigate', async () => {
|
||||
let arlCookie = await session.defaultSession.cookies.get({
|
||||
name: "arl"
|
||||
});
|
||||
if (arlCookie.length > 0) {
|
||||
res(arlCookie[0].value);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
lwin.close();
|
||||
lwin = null;
|
||||
//Delete deezer junk
|
||||
session.defaultSession.clearStorageData();
|
||||
|
||||
event.reply('browserLogin', arl);
|
||||
});
|
2
buildfiles/app/client/.env
Normal file
@ -0,0 +1,2 @@
|
||||
VUE_APP_I18N_LOCALE=en
|
||||
VUE_APP_I18N_FALLBACK_LOCALE=en
|
21
buildfiles/app/client/.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
BIN
buildfiles/app/client/dist/banner.png
vendored
Normal file
After Width: | Height: | Size: 32 KiB |
1
buildfiles/app/client/dist/css/app.db1a9497.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.main[data-v-5697f540]{width:100vw}.notop[data-v-5697f540]{height:100vh;width:100vw}.electron[data-v-5697f540]{height:calc(100vh - 28px);margin-top:28px;width:100vw}@media screen and (max-height:900px){.imagescale[data-v-5697f540]{max-height:50vh}}@media screen and (max-height:600px){.imagescale[data-v-5697f540]{max-height:45vh}}::-webkit-scrollbar{width:10px}::-webkit-scrollbar:horizontal{height:10px}::-webkit-scrollbar-track{background-color:rgba(16,16,16,.26666666666666666);border-radius:5px}::-webkit-scrollbar-thumb{border-radius:5px;background-color:#363636}.v-navigation-drawer__content{overflow-y:hidden!important}.seekbar .v-progress-linear__determinate[data-v-aba2e2b0],.seekbar[data-v-aba2e2b0]{transition:none!important}.topbar[data-v-aba2e2b0]{-webkit-app-region:drag;z-index:6969}.topbarbutton[data-v-aba2e2b0]{-webkit-app-region:no-drag}
|
5
buildfiles/app/client/dist/css/chunk-vendors.86d1a8f3.css
vendored
Normal file
BIN
buildfiles/app/client/dist/favicon.ico
vendored
Normal file
After Width: | Height: | Size: 264 KiB |
BIN
buildfiles/app/client/dist/fonts/Roboto-Black.313a6563.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Black.59eb3601.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-BlackItalic.cc2fadc3.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-BlackItalic.f75569f8.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Bold.50d75e48.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Bold.b52fac2b.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-BoldItalic.4fe0f73c.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-BoldItalic.94008e69.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Light.c73eb1ce.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Light.d26871e8.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-LightItalic.13efe6cb.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-LightItalic.e8eaae90.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Medium.1d659482.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Medium.90d16760.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-MediumItalic.13ec0eb5.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-MediumItalic.83e114c3.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Regular.35b07eb2.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Regular.73f0a88b.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-RegularItalic.4357beb8.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-RegularItalic.f5902d5e.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Thin.ad538a69.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-Thin.d3b47375.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-ThinItalic.5b4a33e1.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/Roboto-ThinItalic.8a96edbb.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/materialdesignicons-webfont.3d1f8fa2.eot
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/materialdesignicons-webfont.3e722fd5.ttf
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/materialdesignicons-webfont.4187121a.woff2
vendored
Normal file
BIN
buildfiles/app/client/dist/fonts/materialdesignicons-webfont.fec1b66a.woff
vendored
Normal file
BIN
buildfiles/app/client/dist/img/banner.8132f8d1.png
vendored
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
buildfiles/app/client/dist/img/shibe.f6383068.png
vendored
Normal file
After Width: | Height: | Size: 67 KiB |
12
buildfiles/app/client/dist/index.html
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>Freezer</title><link href="/css/app.db1a9497.css" rel="preload" as="style"><link href="/css/chunk-vendors.86d1a8f3.css" rel="preload" as="style"><link href="/js/app.e09b4b40.js" rel="preload" as="script"><link href="/js/chunk-vendors.cf48f2e1.js" rel="preload" as="script"><link href="/css/chunk-vendors.86d1a8f3.css" rel="stylesheet"><link href="/css/app.db1a9497.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but Freezer doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/js/chunk-vendors.cf48f2e1.js"></script><script src="/js/app.e09b4b40.js"></script></body></html><style>html {
|
||||
overflow-y: hidden;
|
||||
}</style><script>document.onkeydown = (e) => {
|
||||
let keycode = e.which;
|
||||
if (window.event) keycode = window.event.keyCode;
|
||||
|
||||
if (keycode == 116 || (e.ctrlKey && keycode == 82)) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
}</script>
|
2
buildfiles/app/client/dist/js/app.e09b4b40.js
vendored
Normal file
1
buildfiles/app/client/dist/js/app.e09b4b40.js.map
vendored
Normal file
34
buildfiles/app/client/dist/js/chunk-vendors.cf48f2e1.js
vendored
Normal file
1
buildfiles/app/client/dist/js/chunk-vendors.cf48f2e1.js.map
vendored
Normal file
1
buildfiles/app/client/dist/lastfm.svg
vendored
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="96px" height="96px"><path d="M 10.699219 16.691406 L 9.894531 14.539063 C 9.894531 14.539063 8.585938 15.972656 6.617188 15.972656 C 4.878906 15.972656 3.644531 14.488281 3.644531 12.117188 C 3.644531 9.074219 5.207031 7.988281 6.746094 7.988281 C 8.960938 7.988281 9.667969 9.394531 10.273438 11.199219 L 11.078125 13.671875 C 11.886719 16.070313 13.398438 18 17.757813 18 C 20.882813 18 23 17.058594 23 14.589844 C 23 12.585938 21.839844 11.546875 19.671875 11.050781 L 18.058594 10.707031 C 16.949219 10.460938 16.621094 10.015625 16.621094 9.273438 C 16.621094 8.433594 17.304688 7.9375 18.410156 7.9375 C 19.621094 7.9375 20.277344 8.382813 20.378906 9.445313 L 22.898438 9.148438 C 22.695313 6.925781 21.132813 6.007813 18.5625 6.007813 C 16.296875 6.007813 14.078125 6.851563 14.078125 9.542969 C 14.078125 11.226563 14.90625 12.289063 17 12.78125 L 18.714844 13.179688 C 20 13.476563 20.429688 13.992188 20.429688 14.710938 C 20.429688 15.625 19.519531 15.996094 17.808594 15.996094 C 15.261719 15.996094 14.203125 14.6875 13.597656 12.882813 L 12.769531 10.410156 C 11.707031 7.195313 10.019531 6.011719 6.667969 6.011719 C 2.964844 6.007813 1 8.308594 1 12.214844 C 1 15.972656 2.964844 18 6.492188 18 C 9.339844 18 10.699219 16.691406 10.699219 16.691406 Z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
BIN
buildfiles/app/client/dist/shibe.png
vendored
Normal file
After Width: | Height: | Size: 67 KiB |
11121
buildfiles/app/client/package-lock.json
generated
Normal file
57
buildfiles/app/client/package.json
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "client",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
|
||||
"watch": "vue-cli-service build --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdi/font": "^5.8.55",
|
||||
"axios": "^0.19.2",
|
||||
"roboto-fontface": "*",
|
||||
"vue": "^2.6.12",
|
||||
"vue-esc": "^3.0.1",
|
||||
"vue-i18n": "^8.17.3",
|
||||
"vue-router": "^3.4.9",
|
||||
"vue-socket.io": "^3.0.10",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuetify": "^2.3.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@intlify/vue-i18n-loader": "^1.0.0",
|
||||
"@vue/cli-plugin-eslint": "^4.5.8",
|
||||
"@vue/cli-plugin-router": "^4.5.8",
|
||||
"@vue/cli-service": "^4.5.8",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"sass": "^1.29.0",
|
||||
"sass-loader": "^8.0.0",
|
||||
"vue-cli-plugin-i18n": "~1.0.1",
|
||||
"vue-cli-plugin-vuetify": "~2.0.7",
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"vuetify-loader": "^1.3.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
}
|
BIN
buildfiles/app/client/public/banner.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
buildfiles/app/client/public/favicon.ico
Normal file
After Width: | Height: | Size: 264 KiB |
39
buildfiles/app/client/public/index.html
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>Freezer</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but Freezer doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- Disable global scrollbars -->
|
||||
<style>
|
||||
html {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Disable reloading using CTRL+R -->
|
||||
<script>
|
||||
document.onkeydown = (e) => {
|
||||
let keycode = e.which;
|
||||
if (window.event) keycode = window.event.keyCode;
|
||||
|
||||
if (keycode == 116 || (e.ctrlKey && keycode == 82)) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
1
buildfiles/app/client/public/lastfm.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="96px" height="96px"><path d="M 10.699219 16.691406 L 9.894531 14.539063 C 9.894531 14.539063 8.585938 15.972656 6.617188 15.972656 C 4.878906 15.972656 3.644531 14.488281 3.644531 12.117188 C 3.644531 9.074219 5.207031 7.988281 6.746094 7.988281 C 8.960938 7.988281 9.667969 9.394531 10.273438 11.199219 L 11.078125 13.671875 C 11.886719 16.070313 13.398438 18 17.757813 18 C 20.882813 18 23 17.058594 23 14.589844 C 23 12.585938 21.839844 11.546875 19.671875 11.050781 L 18.058594 10.707031 C 16.949219 10.460938 16.621094 10.015625 16.621094 9.273438 C 16.621094 8.433594 17.304688 7.9375 18.410156 7.9375 C 19.621094 7.9375 20.277344 8.382813 20.378906 9.445313 L 22.898438 9.148438 C 22.695313 6.925781 21.132813 6.007813 18.5625 6.007813 C 16.296875 6.007813 14.078125 6.851563 14.078125 9.542969 C 14.078125 11.226563 14.90625 12.289063 17 12.78125 L 18.714844 13.179688 C 20 13.476563 20.429688 13.992188 20.429688 14.710938 C 20.429688 15.625 19.519531 15.996094 17.808594 15.996094 C 15.261719 15.996094 14.203125 14.6875 13.597656 12.882813 L 12.769531 10.410156 C 11.707031 7.195313 10.019531 6.011719 6.667969 6.011719 C 2.964844 6.007813 1 8.308594 1 12.214844 C 1 15.972656 2.964844 18 6.492188 18 C 9.339844 18 10.699219 16.691406 10.699219 16.691406 Z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
BIN
buildfiles/app/client/public/shibe.png
Normal file
After Width: | Height: | Size: 67 KiB |
537
buildfiles/app/client/src/App.vue
Normal file
@ -0,0 +1,537 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-app v-esc='closePlayer'>
|
||||
|
||||
<v-system-bar
|
||||
:color='$root.settings.lightTheme ? "#f5f5f5" : "#121212"'
|
||||
app
|
||||
class='topbar'
|
||||
v-if='$root.settings.electron'
|
||||
height='28'>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
<span style='position: absolute; left: 45%'>Freezer <span v-if='version'>v{{version}}</span></span>
|
||||
<v-spacer></v-spacer>
|
||||
<v-icon class='topbarbutton mx-2' @click='minimize'>mdi-window-minimize</v-icon>
|
||||
<v-icon class='topbarbutton mx-2' @click='maximize'>mdi-window-maximize</v-icon>
|
||||
<v-icon @click='exitApp' class='topbarbutton mx-2'>mdi-close</v-icon>
|
||||
</v-system-bar>
|
||||
|
||||
<!-- Fullscreen player overlay -->
|
||||
<v-overlay :value='showPlayer' opacity='1.00' z-index="100">
|
||||
<FullscreenPlayer @close='closePlayer' @volumeChange='volume = $root.volume'></FullscreenPlayer>
|
||||
</v-overlay>
|
||||
|
||||
<!-- Drawer/Navigation -->
|
||||
<v-navigation-drawer
|
||||
permanent
|
||||
fixed
|
||||
app
|
||||
mini-variant
|
||||
expand-on-hover
|
||||
><v-list nav dense>
|
||||
|
||||
<!-- Profile -->
|
||||
<v-list-item two-line v-if='$root.profile && $root.profile.picture' class='miniVariant px-0'>
|
||||
<v-list-item-avatar>
|
||||
<img :src='$root.profile.picture.thumb'>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$root.profile.name}}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{$root.profile.id}}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Home link -->
|
||||
<v-list-item link to='/home'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-home</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{$t('Home')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Browse link -->
|
||||
<v-list-item link to='/page?target=channels%2Fexplore'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-earth</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{$t('Browse')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<v-subheader inset>{{$t('Library')}}</v-subheader>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<!-- Tracks -->
|
||||
<v-list-item link to='/library/tracks'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-music-note</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{$t('Tracks')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Playlists -->
|
||||
<v-list-item link to='/library/playlists'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-playlist-music</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{$t('Playlists')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Albums -->
|
||||
<v-list-item link to='/library/albums'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-album</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{$t('Albums')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Artists -->
|
||||
<v-list-item link to='/library/artists'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-account-music</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{$t('Artists')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<v-subheader inset>{{$t('More')}}</v-subheader>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<!-- Settings -->
|
||||
<v-list-item link to='/settings'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-cog</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{$t('Settings')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Downloads, shitty hack if downloads not yet loaded -->
|
||||
<v-list-item link to='/downloads' v-if='$root.downloads.queue'>
|
||||
|
||||
<!-- Download icon -->
|
||||
<v-list-item-icon v-if='!$root.downloads.downloading && $root.downloads.queue.length == 0'>
|
||||
<v-icon>mdi-download</v-icon>
|
||||
</v-list-item-icon>
|
||||
|
||||
<!-- Paused download -->
|
||||
<v-list-item-icon v-if='!$root.downloads.downloading && $root.downloads.queue.length > 0'>
|
||||
<v-icon>mdi-pause</v-icon>
|
||||
</v-list-item-icon>
|
||||
|
||||
<!-- Download in progress -->
|
||||
<v-list-item-icon v-if='$root.downloads.downloading'>
|
||||
<v-progress-circular :value='downloadPercentage' style='top: -2px' class='text-caption'>
|
||||
{{$root.downloads.queue.length + $root.downloads.threads.length}}
|
||||
</v-progress-circular>
|
||||
</v-list-item-icon>
|
||||
|
||||
<v-list-item-title>{{$t('Downloads')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<!-- About -->
|
||||
<v-list-item link to='/about'>
|
||||
<v-list-item-icon>
|
||||
<v-icon v-if='!updateAvailable'>mdi-information</v-icon>
|
||||
<v-icon color='primary' v-if='updateAvailable'>mdi-update</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{$t('About')}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
</v-list>
|
||||
</v-navigation-drawer>
|
||||
|
||||
<v-app-bar app dense>
|
||||
|
||||
<v-btn icon @click='previous'>
|
||||
<v-icon>mdi-arrow-left</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn icon @click='next'>
|
||||
<v-icon>mdi-arrow-right</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<!-- Search -->
|
||||
<v-autocomplete
|
||||
hide-details
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
flat
|
||||
single-line
|
||||
solo
|
||||
clearable
|
||||
hide-no-data
|
||||
:placeholder='$t("Search or paste Deezer URL. Use / to quickly focus.")'
|
||||
:loading='searchLoading'
|
||||
@keyup='search'
|
||||
ref='searchBar'
|
||||
v-model='searchQuery'
|
||||
:search-input.sync='searchInput'
|
||||
:items='suggestions'
|
||||
></v-autocomplete>
|
||||
|
||||
|
||||
</v-app-bar>
|
||||
|
||||
<!-- Main -->
|
||||
<v-main>
|
||||
<v-container
|
||||
class='overflow-y-auto'
|
||||
fluid
|
||||
style='height: calc(100vh - 140px);'>
|
||||
|
||||
<keep-alive include='Search,PlaylistPage,HomeScreen,DeezerPage'>
|
||||
<router-view></router-view>
|
||||
</keep-alive>
|
||||
</v-container>
|
||||
</v-main>
|
||||
|
||||
<!-- Footer -->
|
||||
<v-footer fixed app height='70' class='pa-0'>
|
||||
|
||||
<v-progress-linear
|
||||
height='5'
|
||||
:value='position'
|
||||
style='cursor: pointer;'
|
||||
class='seekbar'
|
||||
@change='seek'
|
||||
background-opacity='0'>
|
||||
</v-progress-linear>
|
||||
|
||||
<v-row no-gutters align='center' ref='footer' class='ma-1'>
|
||||
|
||||
<!-- No track loaded -->
|
||||
<v-col class='col-5 d-none d-sm-flex' v-if='!this.$root.track'>
|
||||
<h3 class='pl-4'>Freezer</h3>
|
||||
</v-col>
|
||||
|
||||
<!-- Track Info -->
|
||||
<v-col class='d-none d-sm-flex' cols='5' v-if='this.$root.track'>
|
||||
<v-img
|
||||
:src='$root.track.albumArt.thumb'
|
||||
height="56"
|
||||
max-width="60"
|
||||
contain>
|
||||
</v-img>
|
||||
<div class='text-truncate flex-column d-flex'>
|
||||
<span class='text-subtitle-1 pl-2 text-no-wrap'>{{this.$root.track.title}}</span>
|
||||
<span class='text-subtitle-2 pl-2 text-no-wrap'>{{this.$root.track.artistString}}</span>
|
||||
</div>
|
||||
</v-col>
|
||||
|
||||
<!-- Controls -->
|
||||
<v-col class='text-center' cols='12' sm='auto'>
|
||||
<v-btn icon large @click.stop='$root.skip(-1)'>
|
||||
<v-icon>mdi-skip-previous</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon x-large @click.stop='$root.toggle'>
|
||||
<v-icon v-if='!$root.isPlaying()'>mdi-play</v-icon>
|
||||
<v-icon v-if='$root.isPlaying()'>mdi-pause</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon large @click.stop='$root.skipNext'>
|
||||
<v-icon>mdi-skip-next</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
|
||||
<!-- Right side -->
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-col cols='0' md='auto' class='d-none d-sm-none d-md-flex justify-center px-2' v-if='this.$root.track'>
|
||||
<span class='text-subtitle-2'>
|
||||
{{$duration($root.position)}} <span class='px-4'>{{qualityText}}</span>
|
||||
</span>
|
||||
</v-col>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<!-- Volume -->
|
||||
<v-col cols='auto' class='d-none d-sm-flex px-2' @click.stop>
|
||||
|
||||
<div style='width: 180px;' class='d-flex'>
|
||||
<v-slider
|
||||
dense
|
||||
hide-details
|
||||
min='0.00'
|
||||
max='1.00'
|
||||
step='0.01'
|
||||
v-model='volume'
|
||||
:prepend-icon='$root.muted ? "mdi-volume-off" : "mdi-volume-high"'
|
||||
@click:prepend='$root.toggleMute()'
|
||||
>
|
||||
<template v-slot:append>
|
||||
<div style='padding-top: 4px;'>
|
||||
{{Math.round(volume * 100)}}%
|
||||
</div>
|
||||
</template>
|
||||
</v-slider>
|
||||
</div>
|
||||
|
||||
</v-col>
|
||||
|
||||
</v-row>
|
||||
</v-footer>
|
||||
|
||||
<!-- Global snackbar -->
|
||||
<v-snackbar timeout='2000' v-model='globalSnackbar'>
|
||||
{{this.$root.globalSnackbar}}
|
||||
<template v-slot:action='{attrs}'>
|
||||
<v-btn text v-bind="attrs" @click='globalSnackbar = false' color='primary'>
|
||||
{{$t("Dismiss")}}
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-snackbar>
|
||||
|
||||
</v-app>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang='scss'>
|
||||
@import 'styles/scrollbar.scss';
|
||||
.v-navigation-drawer__content {
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
</style>
|
||||
<style lang='scss' scoped>
|
||||
.seekbar {
|
||||
transition: none !important;
|
||||
}
|
||||
.seekbar .v-progress-linear__determinate {
|
||||
transition: none !important;
|
||||
}
|
||||
.topbar {
|
||||
-webkit-app-region: drag;
|
||||
z-index: 6969;
|
||||
}
|
||||
.topbarbutton {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import FullscreenPlayer from '@/views/FullscreenPlayer.vue';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
FullscreenPlayer
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
volume: this.$root.volume,
|
||||
showPlayer: false,
|
||||
position: '0.00',
|
||||
searchQuery: '',
|
||||
searchLoading: false,
|
||||
searchInput: null,
|
||||
suggestions: [],
|
||||
preventDoubleEnter: false,
|
||||
cancelSuggestions: false,
|
||||
globalSnackbar: false,
|
||||
version: null,
|
||||
updateAvailable: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Hide fullscreen player overlay
|
||||
closePlayer() {
|
||||
if (this.showPlayer) this.showPlayer = false;
|
||||
this.volume = this.$root.volume;
|
||||
},
|
||||
//Navigation
|
||||
previous() {
|
||||
if (window.history.length == 3) return;
|
||||
this.$router.go(-1);
|
||||
},
|
||||
next() {
|
||||
this.$router.go(1);
|
||||
},
|
||||
async search(event) {
|
||||
//KeyUp event, enter
|
||||
if (event && event.keyCode !== 13) return;
|
||||
//Prevent double navigation
|
||||
if (this.preventDoubleEnter) return;
|
||||
this.preventDoubleEnter = true;
|
||||
setInterval(() => {this.preventDoubleEnter = false}, 50);
|
||||
|
||||
//Check if url
|
||||
let query = this.searchInput;
|
||||
if (query.startsWith('http')) {
|
||||
this.searchLoading = true;
|
||||
let url = new URL(query);
|
||||
|
||||
//Normal link
|
||||
if (url.hostname == 'www.deezer.com' || url.hostname == 'deezer.com' || url.hostname == 'deezer.page.link') {
|
||||
|
||||
//Share link
|
||||
if (url.hostname == 'deezer.page.link') {
|
||||
let res = await this.$axios.get('/fullurl?url=' + encodeURIComponent(query));
|
||||
url = new URL(res.data.url);
|
||||
}
|
||||
|
||||
let supported = ['track', 'artist', 'album', 'playlist'];
|
||||
|
||||
let path = url.pathname.substring(1).split('/');
|
||||
if (path.length == 3) path = path.slice(1);
|
||||
let type = path[0];
|
||||
if (supported.includes(type)) {
|
||||
|
||||
//Dirty lol
|
||||
let res = await this.$axios('/' + path.join('/'));
|
||||
if (res.data) {
|
||||
//Add to queue
|
||||
if (type == 'track') {
|
||||
this.$root.queue.data.splice(this.$root.queue.index + 1, 0, res.data);
|
||||
this.$root.skip(1);
|
||||
}
|
||||
//Show details page
|
||||
if (type == 'artist' || type == 'album' || type == 'playlist') {
|
||||
let query = {};
|
||||
query[type] = JSON.stringify(res.data);
|
||||
this.$router.push({path: `/${type}`, query: query});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.searchLoading = false;
|
||||
} else {
|
||||
//Normal search
|
||||
this.cancelSuggestions = true;
|
||||
this.suggestions = [];
|
||||
this.$router.push({path: '/search', query: {q: query}});
|
||||
}
|
||||
},
|
||||
seek(val) {
|
||||
this.$root.seek(Math.round((val / 100) * this.$root.duration()));
|
||||
},
|
||||
async exitApp() {
|
||||
await this.$root.saveSettings();
|
||||
await this.$root.savePlaybackInfo();
|
||||
const {ipcRenderer} = window.require('electron');
|
||||
ipcRenderer.send('close');
|
||||
},
|
||||
minimize() {
|
||||
const {ipcRenderer} = window.require('electron');
|
||||
ipcRenderer.send('minimize');
|
||||
},
|
||||
maximize() {
|
||||
const {ipcRenderer} = window.require('electron');
|
||||
ipcRenderer.send('maximize');
|
||||
},
|
||||
async checkUpdate() {
|
||||
try {
|
||||
let res = await this.$axios('/updates');
|
||||
if (res.data)
|
||||
this.updateAvailable = true;
|
||||
} catch (_) {
|
||||
this.updateAvailable = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
qualityText() {
|
||||
return `${this.$root.playbackInfo.qualityString}`;
|
||||
},
|
||||
downloadPercentage() {
|
||||
if (!this.$root.downloads.downloading) return 0;
|
||||
|
||||
let downloaded = this.$root.downloads.threads.reduce((a, b) => a + b.downloaded, 0);
|
||||
let size = this.$root.downloads.threads.reduce((a, b) => a + b.size, 0);
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
let p = (downloaded / size) * 100;
|
||||
if (p > 100)
|
||||
p = 100;
|
||||
return Math.round(p);
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
//onClick for footer
|
||||
this.$refs.footer.addEventListener('click', () => {
|
||||
if (this.$root.track) this.showPlayer = true;
|
||||
});
|
||||
|
||||
// /search
|
||||
document.addEventListener('keypress', (e) => {
|
||||
if (e.keyCode != 47) return;
|
||||
this.$refs.searchBar.focus();
|
||||
setTimeout(() => {
|
||||
if (this.searchQuery.startsWith('/')) this.searchQuery = this.searchQuery.substring(1);
|
||||
}, 40);
|
||||
});
|
||||
|
||||
//Wait for volume to load
|
||||
if (this.$root.loadingPromise) await this.$root.loadingPromise;
|
||||
this.volume = this.$root.volume;
|
||||
|
||||
//Check for update
|
||||
this.checkUpdate();
|
||||
},
|
||||
created() {
|
||||
//Go to login if unauthorized
|
||||
if (!this.$root.authorized) {
|
||||
this.$router.push('/login');
|
||||
}
|
||||
|
||||
this.$axios.get('/about').then((res) => {
|
||||
this.version = res.data.version;
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
volume() {
|
||||
if (this.$root.audio) this.$root.audio.volume = this.volume;
|
||||
this.$root.volume = this.volume;
|
||||
},
|
||||
'$root.volume'() {
|
||||
this.volume = this.$root.volume;
|
||||
},
|
||||
//Update position
|
||||
'$root.position'() {
|
||||
this.position = (this.$root.position / this.$root.duration()) * 100;
|
||||
},
|
||||
//Global snackbar
|
||||
'$root.globalSnackbar'() {
|
||||
if (!this.$root.globalSnackbar) return;
|
||||
this.globalSnackbar = true;
|
||||
setTimeout(() => {
|
||||
this.$root.globalSnackbar = null;
|
||||
}, 2000);
|
||||
},
|
||||
//Autofill
|
||||
searchInput(query) {
|
||||
//Filters
|
||||
if (query && query.startsWith('/')) {
|
||||
query = query.substring(1);
|
||||
this.searchInput = query;
|
||||
}
|
||||
if (!query || (query && query.startsWith('http'))) {
|
||||
this.searchLoading = false;
|
||||
this.suggestions = [];
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.$root.settings.showAutocomplete) return;
|
||||
this.searchLoading = true;
|
||||
//Prevent spam
|
||||
setTimeout(() => {
|
||||
if (query != this.searchInput) return;
|
||||
this.$axios.get('/suggestions/' + encodeURIComponent(query)).then((res) => {
|
||||
if (query != this.searchInput) return;
|
||||
//Cancel suggestions to prevent autocompletion when already searched
|
||||
if (this.cancelSuggestions) {
|
||||
this.cancelSuggestions = false;
|
||||
this.searchLoading = false;
|
||||
return;
|
||||
}
|
||||
this.suggestions = res.data;
|
||||
this.searchLoading = false;
|
||||
});
|
||||
}, 300);
|
||||
},
|
||||
searchQuery(q) {
|
||||
this.searchInput = q;
|
||||
this.search(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
193
buildfiles/app/client/src/components/AlbumTile.vue
Normal file
@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-list-item two-line @click='click' v-if='!card' @contextmenu.prevent="menu = true">
|
||||
<v-hover v-slot:default='{hover}'>
|
||||
<v-list-item-avatar>
|
||||
<v-img :src='album.art.thumb'></v-img>
|
||||
<v-overlay absolute :value='hover'>
|
||||
<v-btn icon large @click.stop='play'>
|
||||
<v-icon>mdi-play</v-icon>
|
||||
</v-btn>
|
||||
</v-overlay>
|
||||
</v-list-item-avatar>
|
||||
</v-hover>
|
||||
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>
|
||||
{{album.title}}<span v-if='album.explicit' class='red--text text-overline pl-2'>E</span>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>{{album.artistString}}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<!-- Context menu -->
|
||||
<v-menu v-model='menu' offset-y offset-x absolue>
|
||||
<template v-slot:activator="{on, attrs}">
|
||||
<v-btn v-on='on' v-bind='attrs' icon>
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list dense>
|
||||
<!-- Play album -->
|
||||
<v-list-item dense @click='play'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-play</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Play")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Add to library -->
|
||||
<v-list-item dense @click='library' v-if='!album.library'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-heart</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Add to library")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Remove from library -->
|
||||
<v-list-item dense @click='library' v-if='album.library'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-heart-remove</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Remove from library")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Share -->
|
||||
<v-list-item dense @click='share'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-share-variant</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Share")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Download -->
|
||||
<v-list-item dense @click='download'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-download</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Download")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
|
||||
<v-card v-if='card' max-width='175px' max-height='210px' @click='click'>
|
||||
<v-hover v-slot:default='{hover}'>
|
||||
<div>
|
||||
|
||||
<v-img :src='album.art.thumb'>
|
||||
</v-img>
|
||||
|
||||
<v-overlay absolute :value='hover' opacity='0.5'>
|
||||
<v-btn fab small color='white' @click.stop='play'>
|
||||
<v-icon color='black'>mdi-play</v-icon>
|
||||
</v-btn>
|
||||
</v-overlay>
|
||||
|
||||
</div>
|
||||
</v-hover>
|
||||
|
||||
|
||||
<div class='pa-2 text-subtitle-2 text-center text-truncate'>{{album.title}}</div>
|
||||
|
||||
</v-card>
|
||||
|
||||
<DownloadDialog :tracks='album.tracks' v-if='downloadDialog' @close='downloadDialog = false'></DownloadDialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DownloadDialog from '@/components/DownloadDialog.vue';
|
||||
|
||||
export default {
|
||||
name: 'AlbumTile',
|
||||
components: {DownloadDialog},
|
||||
data() {
|
||||
return {
|
||||
menu: false,
|
||||
hover: false,
|
||||
downloadDialog: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
album: Object,
|
||||
card: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async play() {
|
||||
let album = this.album;
|
||||
//Load album from API if tracks are missing
|
||||
if (album.tracks.length == 0) {
|
||||
let data = await this.$axios.get(`/album/${album.id}`)
|
||||
album = data.data;
|
||||
}
|
||||
//Error handling
|
||||
if (!album) return;
|
||||
|
||||
this.$root.queueSource = {
|
||||
text: album.title,
|
||||
source: 'album',
|
||||
data: album.id
|
||||
};
|
||||
this.$root.replaceQueue(album.tracks);
|
||||
this.$root.playIndex(0);
|
||||
},
|
||||
//On click navigate to details
|
||||
click() {
|
||||
this.$router.push({
|
||||
path: '/album',
|
||||
query: {album: JSON.stringify(this.album)}
|
||||
});
|
||||
this.$emit('clicked')
|
||||
},
|
||||
async library() {
|
||||
if (this.album.library) {
|
||||
//Remove
|
||||
await this.$axios.delete('/library/album?id=' + this.album.id);
|
||||
this.$root.globalSnackbar = this.$t('Removed from library!');
|
||||
this.album.library = false;
|
||||
this.$emit('remove');
|
||||
} else {
|
||||
//Add
|
||||
await this.$axios.put(`/library/album?id=${this.album.id}`);
|
||||
this.$root.globalSnackbar = this.$t('Added to library!');
|
||||
this.album.library = true;
|
||||
}
|
||||
},
|
||||
//Add to downloads
|
||||
async download() {
|
||||
//Fetch tracks if missing
|
||||
let tracks = this.album.tracks;
|
||||
if (!tracks || tracks.length == 0) {
|
||||
let data = await this.$axios.get(`/album/${this.album.id}`)
|
||||
tracks = data.data.tracks;
|
||||
}
|
||||
this.album.tracks = tracks;
|
||||
this.downloadDialog = true;
|
||||
},
|
||||
//Copy link
|
||||
share() {
|
||||
let copyElem = document.createElement('input');
|
||||
copyElem.value = `https://deezer.com/album/${this.album.id}`;
|
||||
document.body.appendChild(copyElem);
|
||||
copyElem.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(copyElem);
|
||||
this.$root.globalSnackbar = this.$t('Link copied!');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
123
buildfiles/app/client/src/components/ArtistTile.vue
Normal file
@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-list-item @click='click' v-if='!card' @contextmenu.prevent="menu = true">
|
||||
<v-list-item-avatar>
|
||||
<v-img :src='artist.picture.thumb'></v-img>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{artist.name}}</v-list-item-title>
|
||||
<v-list-item-subtitle v-if='!tiny'>{{$abbreviation(artist.fans)}} {{$t("fans")}}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<!-- Context menu -->
|
||||
<v-menu v-model='menu' offset-y offset-x absolue>
|
||||
<template v-slot:activator="{on, attrs}">
|
||||
<v-btn v-on='on' v-bind='attrs' icon>
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list dense>
|
||||
<!-- Add library -->
|
||||
<v-list-item dense @click='library' v-if='!artist.library'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-heart</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Add to library")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Remove from library -->
|
||||
<v-list-item dense @click='library' v-if='artist.library'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-heart-remove</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Remove from library")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Share -->
|
||||
<v-list-item dense @click='share'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-share-variant</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Share")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Card version -->
|
||||
<v-card max-height='200px' max-width='200px' v-if='card' @click='click'>
|
||||
<div class='d-flex justify-center'>
|
||||
<v-avatar size='150' class='ma-1'>
|
||||
<v-img :src='artist.picture.thumb'>
|
||||
</v-img>
|
||||
</v-avatar>
|
||||
</div>
|
||||
|
||||
<div class='pa-2 text-subtitle-2 text-center text-truncate'>{{artist.name}}</div>
|
||||
</v-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ArtistTile',
|
||||
data() {
|
||||
return {
|
||||
menu: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
artist: Object,
|
||||
card: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
tiny: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async library() {
|
||||
if (this.artist.library) {
|
||||
//Remove
|
||||
await this.$axios.delete('/library/artist?id=' + this.artist.id);
|
||||
this.$root.globalSnackbar = this.$t('Removed from library!');
|
||||
this.artist.library = false;
|
||||
this.$emit('remove');
|
||||
} else {
|
||||
//Add
|
||||
await this.$axios.put(`/library/artist?id=${this.artist.id}`);
|
||||
this.$root.globalSnackbar = this.$t('Added to library!');
|
||||
this.artist.library = true;
|
||||
}
|
||||
},
|
||||
click() {
|
||||
//Navigate to details
|
||||
this.$router.push({
|
||||
path: '/artist',
|
||||
query: {artist: JSON.stringify(this.artist)}
|
||||
});
|
||||
this.$emit('clicked');
|
||||
},
|
||||
//Copy link
|
||||
share() {
|
||||
let copyElem = document.createElement('input');
|
||||
copyElem.value = `https://deezer.com/artist/${this.artist.id}`;
|
||||
document.body.appendChild(copyElem);
|
||||
copyElem.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(copyElem);
|
||||
this.$root.globalSnackbar = this.$t('Link copied!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
35
buildfiles/app/client/src/components/DeezerChannel.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<v-card
|
||||
width='225px'
|
||||
height='100px'
|
||||
:img='channel.image.thumb'
|
||||
@click='click'
|
||||
>
|
||||
<v-container fill-height class='justify-center'>
|
||||
<v-card-title class='font-weight-black text-truncate text-h6 pa-1'>{{channel.title}}</v-card-title>
|
||||
</v-container>
|
||||
|
||||
</v-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DeezerChannel',
|
||||
props: {
|
||||
channel: Object
|
||||
},
|
||||
methods: {
|
||||
click() {
|
||||
console.log(this.channel.target);
|
||||
this.$router.push({
|
||||
path: '/page',
|
||||
query: {target: this.channel.target}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
132
buildfiles/app/client/src/components/DownloadDialog.vue
Normal file
@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<v-dialog v-model='dShow' max-width='420'>
|
||||
<v-card>
|
||||
|
||||
<v-card-title class='headline'>
|
||||
{{$t("Download")}} {{tracks.length}} {{$t("tracks")}}
|
||||
</v-card-title>
|
||||
<v-card-text class='pb-0'>
|
||||
|
||||
<v-select
|
||||
:label='$t("Quality")'
|
||||
persistent-hint
|
||||
:items='qualities'
|
||||
v-model='qualityString'
|
||||
:hint='$t("Estimated size:") + " " + $filesize(estimatedSize)'
|
||||
></v-select>
|
||||
|
||||
<v-checkbox
|
||||
v-model='autostart'
|
||||
:label='$t("Start downloading")'
|
||||
></v-checkbox>
|
||||
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text @click='$emit("close")'>{{$t("Cancel")}}</v-btn>
|
||||
<v-btn text @click='download'>{{$t("Download")}}</v-btn>
|
||||
</v-card-actions>
|
||||
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DownloadDialog',
|
||||
props: {
|
||||
tracks: Array,
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
playlistName: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shown: true,
|
||||
qualities: [
|
||||
this.$t('Settings quality'),
|
||||
'MP3 128kbps',
|
||||
'MP3 320kbps',
|
||||
'FLAC ~1441kbps'
|
||||
],
|
||||
qualityString: this.$t('Settings quality'),
|
||||
autostart: true,
|
||||
dShow: this.show
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Get quality int from select
|
||||
qualityInt() {
|
||||
let i = this.qualities.indexOf(this.qualityString);
|
||||
if (i == 1) return 1;
|
||||
if (i == 2) return 3;
|
||||
if (i == 3) return 9;
|
||||
return this.$root.settings.downloadsQuality;
|
||||
},
|
||||
//Add files to download queue
|
||||
async download() {
|
||||
let data = {
|
||||
tracks: this.tracks,
|
||||
playlistName: this.playlistName,
|
||||
quality: null
|
||||
}
|
||||
if (this.qualities.indexOf(this.qualityString) != 0 && this.qualityString) {
|
||||
data['quality'] = this.qualityInt();
|
||||
}
|
||||
await this.$axios.post(`/downloads`, data);
|
||||
|
||||
if (this.autostart) this.$axios.put('/download');
|
||||
this.$emit("close");
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
estimatedSize() {
|
||||
let qi = this.qualityInt();
|
||||
let duration = this.tracks.reduce((a, b) => a + (b.duration / 1000), 0);
|
||||
|
||||
//Magic numbers = bitrate / 8 * 1024 = bytes per second
|
||||
switch (qi) {
|
||||
case 1:
|
||||
return duration * 16384;
|
||||
case 3:
|
||||
return duration * 40960;
|
||||
case 9:
|
||||
//FLAC is 1144, because more realistic
|
||||
return duration * 146432;
|
||||
}
|
||||
return duration * this.$root.settings.downloadsQuality;
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
//Prevent errors on closing with mouse
|
||||
show() {
|
||||
this.dShow = this.show;
|
||||
},
|
||||
dShow() {
|
||||
if (!this.dShow) this.$emit('close');
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
//Auto download
|
||||
if (!this.$root.settings.downloadDialog) {
|
||||
this.download();
|
||||
setInterval(() => {
|
||||
this.$emit('close');
|
||||
this.dShow = false;
|
||||
}, 50);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
102
buildfiles/app/client/src/components/LibraryAlbums.vue
Normal file
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<v-list>
|
||||
|
||||
<v-overlay v-if='loading'>
|
||||
<v-progress-circular indeterminate></v-progress-circular>
|
||||
</v-overlay>
|
||||
|
||||
<!-- Sort -->
|
||||
<div class='px-4 d-flex' style='max-height: 50px;' v-if='!loading'>
|
||||
<div class='text-overline pt-1 mx-2'>
|
||||
{{albums.length}} {{$t("Albums")}}
|
||||
</div>
|
||||
<div style="max-width: 200px;" class='mx-2'>
|
||||
<v-select class='px-2' dense solo :items='sortTypes' @change='sort' :label='$t("Sort by")'>
|
||||
</v-select>
|
||||
</div>
|
||||
<div class='px-2' @click='reverseSort'>
|
||||
<v-btn icon>
|
||||
<v-icon v-if='isReversed'>mdi-sort-reverse-variant</v-icon>
|
||||
<v-icon v-if='!isReversed'>mdi-sort-variant</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-lazy max-height="100" v-for='(album, index) in albums' :key='album.id'>
|
||||
<AlbumTile :album='album' @remove='removed(index)'></AlbumTile>
|
||||
</v-lazy>
|
||||
|
||||
</v-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AlbumTile from '@/components/AlbumTile.vue';
|
||||
|
||||
export default {
|
||||
name: 'LibraryAlbums',
|
||||
data() {
|
||||
return {
|
||||
albums: [],
|
||||
loading: false,
|
||||
|
||||
//Sort
|
||||
isReversed: false,
|
||||
sortTypes: [
|
||||
this.$t('Date Added'),
|
||||
this.$t('Name (A-Z)'),
|
||||
this.$t('Artist (A-Z)')
|
||||
],
|
||||
unsorted: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Load data
|
||||
async load() {
|
||||
this.loading = true;
|
||||
let res = await this.$axios.get(`/library/albums`);
|
||||
if (res.data && res.data.data) {
|
||||
this.albums = res.data.data;
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
removed(index) {
|
||||
this.albums.splice(index, 1);
|
||||
},
|
||||
//Sort changed
|
||||
async sort(type) {
|
||||
let index = this.sortTypes.indexOf(type);
|
||||
//Copy original
|
||||
if (!this.unsorted)
|
||||
this.unsorted = JSON.parse(JSON.stringify(this.albums));
|
||||
|
||||
//Using indexes, so it can be translated later
|
||||
this.isReversed = false;
|
||||
switch (index) {
|
||||
//Default
|
||||
case 0:
|
||||
this.albums = JSON.parse(JSON.stringify(this.unsorted));
|
||||
break;
|
||||
//Name
|
||||
case 1:
|
||||
this.albums = this.albums.sort((a, b) => {return a.title.localeCompare(b.title);});
|
||||
break;
|
||||
//Artist
|
||||
case 2:
|
||||
this.albums = this.albums.sort((a, b) => {return a.artistString.localeCompare(b.artistString);});
|
||||
break;
|
||||
}
|
||||
},
|
||||
async reverseSort() {
|
||||
this.isReversed = !this.isReversed;
|
||||
this.albums.reverse();
|
||||
},
|
||||
},
|
||||
components: {
|
||||
AlbumTile
|
||||
},
|
||||
mounted() {
|
||||
//Initial load
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
</script>
|
97
buildfiles/app/client/src/components/LibraryArtists.vue
Normal file
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<v-list>
|
||||
|
||||
<v-overlay v-if='loading'>
|
||||
<v-progress-circular indeterminate></v-progress-circular>
|
||||
</v-overlay>
|
||||
|
||||
<!-- Sort -->
|
||||
<div class='px-4 d-flex' style='max-height: 50px;' v-if='!loading'>
|
||||
<div class='text-overline pt-1 mx-2'>
|
||||
{{artists.length}} {{$t("Artists")}}
|
||||
</div>
|
||||
<div style="max-width: 200px;" class='mx-2'>
|
||||
<v-select class='px-2' dense solo :items='sortTypes' @change='sort' :label='$t("Sort by")'>
|
||||
</v-select>
|
||||
</div>
|
||||
<div class='px-2' @click='reverseSort'>
|
||||
<v-btn icon>
|
||||
<v-icon v-if='isReversed'>mdi-sort-reverse-variant</v-icon>
|
||||
<v-icon v-if='!isReversed'>mdi-sort-variant</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-lazy max-height="100" v-for='(artist, index) in artists' :key='artist.id'>
|
||||
<ArtistTile :artist='artist' @remove='removed(index)'></ArtistTile>
|
||||
</v-lazy>
|
||||
|
||||
</v-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ArtistTile from '@/components/ArtistTile.vue';
|
||||
|
||||
export default {
|
||||
name: 'LibraryArtists',
|
||||
components: {
|
||||
ArtistTile
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
artists: [],
|
||||
loading: false,
|
||||
|
||||
//Sort
|
||||
isReversed: false,
|
||||
sortTypes: [
|
||||
this.$t('Date Added'),
|
||||
this.$t('Name (A-Z)')
|
||||
],
|
||||
unsorted: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Load data
|
||||
async load() {
|
||||
this.loading = true;
|
||||
let res = await this.$axios.get(`/library/artists`);
|
||||
if (res.data && res.data.data) {
|
||||
this.artists = res.data.data;
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
removed(index) {
|
||||
this.artists.splice(index, 1);
|
||||
},
|
||||
//Sort changed
|
||||
async sort(type) {
|
||||
let index = this.sortTypes.indexOf(type);
|
||||
//Copy original
|
||||
if (!this.unsorted)
|
||||
this.unsorted = JSON.parse(JSON.stringify(this.artists));
|
||||
|
||||
//Using indexes, so it can be translated later
|
||||
this.isReversed = false;
|
||||
switch (index) {
|
||||
//Default
|
||||
case 0:
|
||||
this.artists = JSON.parse(JSON.stringify(this.unsorted));
|
||||
break;
|
||||
//Name
|
||||
case 1:
|
||||
this.artists = this.artists.sort((a, b) => {return a.name.localeCompare(b.name);});
|
||||
break;
|
||||
}
|
||||
},
|
||||
async reverseSort() {
|
||||
this.isReversed = !this.isReversed;
|
||||
this.artists.reverse();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
//Initial load
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
</script>
|
72
buildfiles/app/client/src/components/LibraryHistory.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<div v-if='loading'>
|
||||
<v-progress-circular indeterminate class='ma-4'></v-progress-circular>
|
||||
</div>
|
||||
|
||||
<v-list v-if='!loading'>
|
||||
<v-list-item v-if='!$root.settings.logListen'>
|
||||
<v-list-item-avatar>
|
||||
<v-icon class='yellow--text'>mdi-alert</v-icon>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>
|
||||
{{$t("Stream logging is disabled!")}}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
{{$t("Enable it in settings for history to work properly.")}}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<v-lazy v-for='(track, index) in tracks' :key='track.id + "INDEX" + index.toString()' max-height='100'>
|
||||
<TrackTile :track='track' @click='play(index)'></TrackTile>
|
||||
</v-lazy>
|
||||
</v-list>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import TrackTile from '@/components/TrackTile.vue';
|
||||
|
||||
export default {
|
||||
name: 'LibraryHistory',
|
||||
components: {
|
||||
TrackTile
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
tracks: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async load() {
|
||||
this.loading = true;
|
||||
|
||||
//Fetch
|
||||
let res = await this.$axios.get('/history');
|
||||
if (res.data) this.tracks = res.data;
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
//Load as queue and play
|
||||
play(index) {
|
||||
this.$root.queue.source = {
|
||||
text: this.$t('History'),
|
||||
source: 'history',
|
||||
data: null
|
||||
};
|
||||
this.$root.replaceQueue(this.tracks);
|
||||
this.$root.playIndex(index);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
//Load on start
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
</script>
|
120
buildfiles/app/client/src/components/LibraryPlaylists.vue
Normal file
@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<v-list>
|
||||
|
||||
<v-overlay v-if='loading'>
|
||||
<v-progress-circular indeterminate></v-progress-circular>
|
||||
</v-overlay>
|
||||
|
||||
<div class='d-flex'>
|
||||
<!-- Create playlist -->
|
||||
<v-btn class='ma-2 ml-3' color='primary' @click='popup = true'>
|
||||
<v-icon left>mdi-playlist-plus</v-icon>
|
||||
{{$t("Create new playlist")}}
|
||||
</v-btn>
|
||||
|
||||
<!-- Sort -->
|
||||
<div class='mt-1 px-2 d-flex'>
|
||||
<div class='text-overline pt-1 mx-2'>
|
||||
{{playlists.length}} {{$t("Playlists")}}
|
||||
</div>
|
||||
<div style="max-width: 200px;" class='mx-2'>
|
||||
<v-select class='px-2' dense solo :items='sortTypes' @change='sort' :label='$t("Sort by")'>
|
||||
</v-select>
|
||||
</div>
|
||||
<div class='px-2' @click='reverseSort'>
|
||||
<v-btn icon>
|
||||
<v-icon v-if='isReversed'>mdi-sort-reverse-variant</v-icon>
|
||||
<v-icon v-if='!isReversed'>mdi-sort-variant</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<v-dialog max-width="400px" v-model='popup'>
|
||||
<PlaylistPopup @created='playlistCreated'></PlaylistPopup>
|
||||
</v-dialog>
|
||||
|
||||
<v-lazy max-height="100" v-for='(playlist, index) in playlists' :key='playlist.id'>
|
||||
<PlaylistTile :playlist='playlist' @remove='removed(index)'></PlaylistTile>
|
||||
</v-lazy>
|
||||
|
||||
</v-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PlaylistTile from '@/components/PlaylistTile.vue';
|
||||
import PlaylistPopup from '@/components/PlaylistPopup.vue';
|
||||
|
||||
export default {
|
||||
name: 'LibraryPlaylists',
|
||||
components: {
|
||||
PlaylistTile, PlaylistPopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
playlists: [],
|
||||
loading: false,
|
||||
popup: false,
|
||||
|
||||
//Sort
|
||||
isReversed: false,
|
||||
sortTypes: [
|
||||
this.$t('Date Added'),
|
||||
this.$t('Name (A-Z)'),
|
||||
],
|
||||
unsorted: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Load data
|
||||
async load() {
|
||||
this.loading = true;
|
||||
let res = await this.$axios.get(`/library/playlists`);
|
||||
if (res.data && res.data.data) {
|
||||
this.playlists = res.data.data;
|
||||
}
|
||||
this.loading = false;
|
||||
|
||||
},
|
||||
//Playlist created, update list
|
||||
playlistCreated() {
|
||||
this.popup = false;
|
||||
this.playlists = [];
|
||||
this.load();
|
||||
},
|
||||
//On playlist remove
|
||||
removed(i) {
|
||||
this.playlists.splice(i, 1);
|
||||
},
|
||||
//Sort changed
|
||||
async sort(type) {
|
||||
let index = this.sortTypes.indexOf(type);
|
||||
//Copy original
|
||||
if (!this.unsorted)
|
||||
this.unsorted = JSON.parse(JSON.stringify(this.playlists));
|
||||
|
||||
//Using indexes, so it can be translated later
|
||||
this.isReversed = false;
|
||||
switch (index) {
|
||||
//Default
|
||||
case 0:
|
||||
this.playlists = JSON.parse(JSON.stringify(this.unsorted));
|
||||
break;
|
||||
//Name
|
||||
case 1:
|
||||
this.playlists = this.playlists.sort((a, b) => {return a.title.localeCompare(b.title);});
|
||||
break;
|
||||
}
|
||||
},
|
||||
async reverseSort() {
|
||||
this.isReversed = !this.isReversed;
|
||||
this.playlists.reverse();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
//Initial load
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
</script>
|
163
buildfiles/app/client/src/components/LibraryTracks.vue
Normal file
@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div v-scroll.self='scroll'>
|
||||
<div class='px-4 pt-2 d-flex' style='max-height: 50px;'>
|
||||
<div class='text-overline px-2 pt-1'>
|
||||
{{count}} {{$t("TRACKS")}}
|
||||
</div>
|
||||
<div style="max-width: 200px;" class='d-flex mx-2'>
|
||||
<v-select class='px-2' dense solo :items='sortTypes' @change='sort' :label='$t("Sort by")'>
|
||||
</v-select>
|
||||
</div>
|
||||
<div class='px-2' @click='reverseSort'>
|
||||
<v-btn icon>
|
||||
<v-icon v-if='isReversed'>mdi-sort-reverse-variant</v-icon>
|
||||
<v-icon v-if='!isReversed'>mdi-sort-variant</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-list :height='height' class='overflow-y-auto'>
|
||||
<v-lazy
|
||||
v-for='(track, index) in tracks'
|
||||
:key='index + "t" + track.id'
|
||||
max-height="100"
|
||||
><TrackTile :track='track' @click='play(index)' @remove='removedTrack(index)'>
|
||||
</TrackTile>
|
||||
</v-lazy>
|
||||
|
||||
<div class='text-center' v-if='loading'>
|
||||
<v-progress-circular indeterminate></v-progress-circular>
|
||||
</div>
|
||||
</v-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TrackTile from '@/components/TrackTile.vue';
|
||||
|
||||
export default {
|
||||
name: 'LibraryTracks',
|
||||
components: {
|
||||
TrackTile
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
tracks: [],
|
||||
count: 0,
|
||||
sortTypes: [
|
||||
this.$t('Date Added'),
|
||||
this.$t('Name (A-Z)'),
|
||||
this.$t('Artist (A-Z)'),
|
||||
this.$t('Album (A-Z)')
|
||||
],
|
||||
tracksUnsorted: null,
|
||||
isReversed: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
height: String
|
||||
},
|
||||
methods: {
|
||||
scroll(event) {
|
||||
let loadOffset = event.target.scrollHeight - event.target.offsetHeight - 100;
|
||||
if (event.target.scrollTop > loadOffset) {
|
||||
if (!this.loading) this.load();
|
||||
}
|
||||
},
|
||||
//Load initial data
|
||||
initialLoad() {
|
||||
this.loading = true;
|
||||
this.$axios.get(`/library/tracks`).then((res) => {
|
||||
this.tracks = res.data.data;
|
||||
this.count = res.data.count;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
//Load more tracks
|
||||
load() {
|
||||
if (this.tracks.length >= this.count) return;
|
||||
this.loading = true;
|
||||
//Library Favorites = playlist
|
||||
let id = this.$root.profile.favoritesPlaylist;
|
||||
let offset = this.tracks.length;
|
||||
this.$axios.get(`/playlist/${id}?start=${offset}`).then((res) => {
|
||||
this.tracks.push(...res.data.tracks);
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
//Load all tracks
|
||||
async loadAll() {
|
||||
this.loading = true;
|
||||
let id = this.$root.profile.favoritesPlaylist;
|
||||
let res = await this.$axios.get(`/playlist/${id}?full=iguess`);
|
||||
if (res.data && res.data.tracks) {
|
||||
this.tracks.push(...res.data.tracks.slice(this.tracks.length));
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
//Play track
|
||||
async play(index) {
|
||||
this.$root.queue.source = {
|
||||
text: 'Loved tracks',
|
||||
source: 'playlist',
|
||||
data: this.$root.profile.favoritesPlaylist
|
||||
};
|
||||
this.$root.replaceQueue(this.tracks);
|
||||
this.$root.playIndex(index);
|
||||
|
||||
//Load all tracks
|
||||
if (this.tracks.length < this.count) {
|
||||
this.loadAll().then(() => {
|
||||
this.$root.replaceQueue(this.tracks);
|
||||
});
|
||||
}
|
||||
},
|
||||
//Sort changed
|
||||
async sort(type) {
|
||||
let index = this.sortTypes.indexOf(type);
|
||||
//Preload all tracks
|
||||
if (this.tracks.length < this.count)
|
||||
await this.loadAll();
|
||||
//Copy original
|
||||
if (!this.tracksUnsorted)
|
||||
this.tracksUnsorted = JSON.parse(JSON.stringify(this.tracks));
|
||||
|
||||
//Using indexes, so it can be translated later
|
||||
this.isReversed = false;
|
||||
switch (index) {
|
||||
//Default
|
||||
case 0:
|
||||
this.tracks = JSON.parse(JSON.stringify(this.tracksUnsorted));
|
||||
break;
|
||||
//Name
|
||||
case 1:
|
||||
this.tracks = this.tracks.sort((a, b) => {return a.title.localeCompare(b.title);});
|
||||
break;
|
||||
//Artist
|
||||
case 2:
|
||||
this.tracks = this.tracks.sort((a, b) => {return a.artistString.localeCompare(b.artistString);});
|
||||
break;
|
||||
//Album
|
||||
case 3:
|
||||
this.tracks = this.tracks.sort((a, b) => {return a.album.title.localeCompare(b.album.title);});
|
||||
break;
|
||||
}
|
||||
},
|
||||
async reverseSort() {
|
||||
//Preload tracks if not sorted yet
|
||||
if (this.tracks.length < this.count)
|
||||
await this.sort(0);
|
||||
this.isReversed = !this.isReversed;
|
||||
this.tracks.reverse();
|
||||
},
|
||||
removedTrack(index) {
|
||||
this.tracks.splice(index, 1);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initialLoad();
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
126
buildfiles/app/client/src/components/Lyrics.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div :style='"max-height: " + height' class='overflow-y-auto' ref='content'>
|
||||
<div class='text-center my-4'>
|
||||
<v-progress-circular indeterminate v-if='loading'></v-progress-circular>
|
||||
</div>
|
||||
|
||||
<div v-if='!loading && lyrics && lyrics.lyrics.length > 0' class='text-center'>
|
||||
<div
|
||||
v-for='(lyric, index) in lyrics.lyrics'
|
||||
:key='lyric.offset'
|
||||
class='my-6 mx-4 pa-2 rounded'
|
||||
:class='{"grey darken-3": playingNow(index)}'
|
||||
@click='seekTo(index)'>
|
||||
<span
|
||||
class='my-8'
|
||||
:class='{"text-h6 font-weight-regular": !playingNow(index), "text-h5 font-weight-bold": playingNow(index)}'
|
||||
:ref='"l"+index'
|
||||
>
|
||||
{{lyric.text}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Unsynchronized -->
|
||||
<div v-if='!loading && lyrics && lyrics.text.length > 0 && lyrics.lyrics.length == 0' class='text-center'>
|
||||
<span v-for='(lyric, index) in lyrics.text' :key='"US" + index' class='my-8 mx-4'>
|
||||
<span class='my-8 text-h6 font-weight-regular'>
|
||||
{{lyric}}
|
||||
</span>
|
||||
<br>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-if='!loading && (!lyrics || (lyrics.text.length == 0 && lyrics.lyrics.length == 0))' class='pa-4 text-center'>
|
||||
<span class='red--text text-h5'>
|
||||
{{$t("Error loading lyrics or lyrics not found!")}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Lyrics',
|
||||
props: {
|
||||
songId: String,
|
||||
height: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cSongId: this.songId,
|
||||
loading: true,
|
||||
lyrics: null,
|
||||
currentLyricIndex: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Load data from API
|
||||
async load() {
|
||||
this.loading = true;
|
||||
this.lyrics = null;
|
||||
try {
|
||||
|
||||
let res = await this.$axios.get(`/lyrics/${this.songId}`);
|
||||
if (res.data && res.data.lyrics) this.lyrics = res.data;
|
||||
|
||||
} catch (e) {true;}
|
||||
this.loading = false;
|
||||
},
|
||||
//Wether current lyric is playing rn
|
||||
playingNow(i) {
|
||||
if (!this.$root.audio) return false;
|
||||
//First & last lyric check
|
||||
if (i == this.lyrics.lyrics.length - 1) {
|
||||
if (this.lyrics.lyrics[i].offset <= this.$root.position) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.$root.position >= this.lyrics.lyrics[i].offset && this.$root.position < this.lyrics.lyrics[i+1].offset) return true;
|
||||
return false;
|
||||
},
|
||||
//Get index of current lyric
|
||||
currentLyric() {
|
||||
if (!this.$root.audio) return 0;
|
||||
return this.lyrics.lyrics.findIndex((l) => {
|
||||
return this.playingNow(this.lyrics.lyrics.indexOf(l));
|
||||
});
|
||||
},
|
||||
//Scroll to currently playing lyric
|
||||
scrollLyric() {
|
||||
if (!this.lyrics || !this.lyrics.lyrics || this.lyrics.lyrics.length == 0) return;
|
||||
|
||||
//Prevent janky scrolling
|
||||
if (this.currentLyricIndex == this.currentLyric()) return;
|
||||
this.currentLyricIndex = this.currentLyric();
|
||||
|
||||
if (!this.$refs["l"+this.currentLyricIndex]) return;
|
||||
this.$refs.content.scrollTo({
|
||||
top: this.$refs["l"+this.currentLyricIndex][0].offsetTop - (window.innerHeight / 2.42),
|
||||
behavior: 'smooth'
|
||||
});
|
||||
},
|
||||
//Seek to lyric in song
|
||||
seekTo(i) {
|
||||
this.$root.seek(this.lyrics.lyrics[i].offset);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
watch: {
|
||||
songId() {
|
||||
//Load on song id change
|
||||
if (this.cSongId != this.songId) {
|
||||
this.cSongId = this.songId;
|
||||
this.load();
|
||||
}
|
||||
},
|
||||
'$root.position'() {
|
||||
this.scrollLyric();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
109
buildfiles/app/client/src/components/PlaylistPopup.vue
Normal file
@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<!-- Create playlist -->
|
||||
<v-card class='text-center pa-2' v-if='!addToPlaylist'>
|
||||
<v-card-text>
|
||||
<p primary-title class='display-1'>{{$t("Create playlist")}}</p>
|
||||
<v-text-field label='Title' class='ma-2' v-model='title'></v-text-field>
|
||||
<v-textarea class='mx-2' v-model='description' label='Description' rows='1' auto-grow></v-textarea>
|
||||
<v-select class='mx-2' v-model='type' :items='types' label='Type'></v-select>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn class='primary' :loading='createLoading' @click='create'>{{$t("Create")}}</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
||||
<!-- Add to playlist -->
|
||||
<v-card class='text-center pa-2' v-if='addToPlaylist'>
|
||||
<v-card-text>
|
||||
<p primary-title class='display-1'>{{$t("Add to playlist")}}</p>
|
||||
<v-btn block class='mb-1' @click='addToPlaylist = false'>
|
||||
<v-icon left>mdi-playlist-plus</v-icon>
|
||||
{{$t("Create new")}}
|
||||
</v-btn>
|
||||
<v-list>
|
||||
<div v-for='playlist in playlists' :key='playlist.id'>
|
||||
<v-list-item
|
||||
v-if='playlist.user.id == $root.profile.id'
|
||||
@click='addTrack(playlist)'
|
||||
dense>
|
||||
<v-list-item-avatar>
|
||||
<v-img :src='playlist.image.thumb'></v-img>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-title>{{playlist.title}}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</div>
|
||||
|
||||
<v-progress-circular indeterminate v-if='loading'></v-progress-circular>
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PlaylistPopup',
|
||||
data() {
|
||||
return {
|
||||
//Make mutable
|
||||
addToPlaylist: this.track?true:false,
|
||||
|
||||
title: '',
|
||||
description: '',
|
||||
type: 'Private',
|
||||
types: ['Private', 'Public'],
|
||||
createLoading: false,
|
||||
|
||||
loading: false,
|
||||
playlists: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
track: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Create playlist
|
||||
async create() {
|
||||
this.createLoading = true;
|
||||
|
||||
await this.$axios.post('/playlist', {
|
||||
description: this.description,
|
||||
title: this.title,
|
||||
type: this.type.toLowerCase(),
|
||||
track: this.track ? this.track.id : null
|
||||
});
|
||||
|
||||
this.createLoading = false;
|
||||
this.$emit('created');
|
||||
this.$emit('close');
|
||||
this.$root.globalSnackbar = this.$t('Added to playlist!');
|
||||
},
|
||||
//Add track to playlist
|
||||
async addTrack(playlist) {
|
||||
await this.$axios.post(`/playlist/${playlist.id}/tracks`, {track: this.track.id});
|
||||
this.$emit('close');
|
||||
this.$root.globalSnackbar = this.$t('Added to playlist!');
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
//Load playlists, if adding to playlist
|
||||
if (this.track) {
|
||||
this.loading = true;
|
||||
|
||||
let res = await this.$axios.get(`/library/playlists`);
|
||||
this.playlists = res.data.data;
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
207
buildfiles/app/client/src/components/PlaylistTile.vue
Normal file
@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- List tile -->
|
||||
<v-list-item @click='click' v-if='!card' @contextmenu.prevent="menu = true">
|
||||
<v-hover v-slot:default='{hover}'>
|
||||
<v-list-item-avatar>
|
||||
<v-img :src='playlist.image.thumb'></v-img>
|
||||
<v-overlay absolute :value='hover'>
|
||||
<v-btn icon large @click.stop='play'>
|
||||
<v-icon>mdi-play</v-icon>
|
||||
</v-btn>
|
||||
</v-overlay>
|
||||
</v-list-item-avatar>
|
||||
</v-hover>
|
||||
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{playlist.title}}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{$numberString(playlist.trackCount)}} {{$t("tracks")}}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<!-- Context menu -->
|
||||
<v-menu v-model='menu' offset-y offset-x absolue>
|
||||
<template v-slot:activator="{on, attrs}">
|
||||
<v-btn v-on='on' v-bind='attrs' icon>
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list dense>
|
||||
<!-- Play -->
|
||||
<v-list-item dense @click='play'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-play</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t('Play')}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Add to library -->
|
||||
<v-list-item dense v-if='!canRemove && !playlist.library' @click='library'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-heart</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t('Add to library')}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Remove -->
|
||||
<v-list-item dense v-if='canRemove' @click='remove'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-playlist-remove</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t('Remove from library')}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Share -->
|
||||
<v-list-item dense @click='share'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-share-variant</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Share")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Download -->
|
||||
<v-list-item dense @click='download'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-download</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t('Download')}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Card -->
|
||||
<v-card v-if='card' max-width='175px' max-height='175px' @click='click' rounded>
|
||||
<v-hover v-slot:default='{hover}'>
|
||||
<div>
|
||||
|
||||
<v-img :src='playlist.image.thumb'>
|
||||
</v-img>
|
||||
|
||||
<v-overlay absolute :value='hover' opacity='0.5'>
|
||||
<v-btn fab small color='white' @click.stop='play'>
|
||||
<v-icon color='black'>mdi-play</v-icon>
|
||||
</v-btn>
|
||||
</v-overlay>
|
||||
|
||||
</div>
|
||||
</v-hover>
|
||||
</v-card>
|
||||
|
||||
<DownloadDialog :playlistName='playlist.title' :tracks='tracks' v-if='downloadDialog' @close='downloadDialog = false'></DownloadDialog>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DownloadDialog from '@/components/DownloadDialog.vue';
|
||||
|
||||
export default {
|
||||
name: 'PlaylistTile',
|
||||
components: {DownloadDialog},
|
||||
data() {
|
||||
return {
|
||||
menu: false,
|
||||
hover: false,
|
||||
downloadDialog: false,
|
||||
tracks: null
|
||||
}
|
||||
},
|
||||
props: {
|
||||
playlist: Object,
|
||||
card: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async play() {
|
||||
let playlist = this.playlist;
|
||||
//Load if no tracks
|
||||
if (!playlist || playlist.tracks.length == 0)
|
||||
playlist = (await this.$axios.get(`/playlist/${playlist.id}?full=iguess`)).data;
|
||||
if (!playlist) return;
|
||||
|
||||
//Play
|
||||
this.$root.queue.source = {
|
||||
text: playlist.title,
|
||||
source: 'playlist',
|
||||
data: playlist.id
|
||||
};
|
||||
this.$root.replaceQueue(playlist.tracks);
|
||||
this.$root.playIndex(0);
|
||||
|
||||
//Load all tracks
|
||||
if (playlist.tracks.length != playlist.trackCount) {
|
||||
let data = await this.$axios.get(`/playlist/${playlist.id}?full=iguess`);
|
||||
playlist = data.data;
|
||||
}
|
||||
},
|
||||
//On click navigate to details
|
||||
click() {
|
||||
this.$router.push({
|
||||
path: '/playlist',
|
||||
query: {playlist: JSON.stringify(this.playlist)}
|
||||
});
|
||||
},
|
||||
async remove() {
|
||||
//Delete own playlist
|
||||
if (this.playlist.user.id == this.$root.profile.id) {
|
||||
await this.$axios.delete(`/playlist/${this.playlist.id}`);
|
||||
this.$root.globalSnackbar = this.$t('Playlist deleted!');
|
||||
} else {
|
||||
//Remove from library
|
||||
await this.$axios.get('/library/playlist&id=' + this.playlist.id);
|
||||
this.$root.globalSnackbar = this.$t('Removed from library!');
|
||||
}
|
||||
|
||||
this.$emit('remove');
|
||||
},
|
||||
async download() {
|
||||
let tracks = this.playlist.tracks;
|
||||
if (tracks.length < this.playlist.trackCount) {
|
||||
let data = await this.$axios.get(`/playlist/${this.playlist.id}?full=iguess`);
|
||||
tracks = data.data.tracks;
|
||||
}
|
||||
this.tracks = tracks;
|
||||
this.downloadDialog = true;
|
||||
},
|
||||
async library() {
|
||||
await this.$axios.put(`/library/playlist?id=${this.playlist.id}`);
|
||||
this.$root.globalSnackbar = this.$t('Added to library!');
|
||||
this.playlist.library = true;
|
||||
},
|
||||
//Copy link
|
||||
share() {
|
||||
let copyElem = document.createElement('input');
|
||||
copyElem.value = `https://deezer.com/playlist/${this.playlist.id}`;
|
||||
document.body.appendChild(copyElem);
|
||||
copyElem.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(copyElem);
|
||||
this.$root.globalSnackbar = this.$t('Link copied!');
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
canRemove() {
|
||||
//Own playlist
|
||||
if (this.$root.profile.id == this.playlist.user.id || this.playlist.library) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
</script>
|
50
buildfiles/app/client/src/components/SmartTrackList.vue
Normal file
@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<v-card max-width='175px' max-height='210px' @click='play' :loading='loading'>
|
||||
<v-img :src='stl.cover.thumb'>
|
||||
</v-img>
|
||||
|
||||
<div class='pa-2 text-subtitle-2 text-center text-truncate'>{{stl.title}}</div>
|
||||
</v-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SmartTrackList',
|
||||
props: {
|
||||
stl: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Load stt as source
|
||||
async play() {
|
||||
this.loading = true;
|
||||
|
||||
//Load data
|
||||
let res = await this.$axios.get('/smarttracklist/' + this.stl.id);
|
||||
if (!res.data) {
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//Send to player
|
||||
this.$root.queue.source = {
|
||||
text: this.stl.title,
|
||||
source: 'smarttracklist',
|
||||
data: this.stl.id
|
||||
};
|
||||
this.$root.replaceQueue(res.data);
|
||||
this.$root.playIndex(0);
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
260
buildfiles/app/client/src/components/TrackTile.vue
Normal file
@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<v-list-item two-line @click='$emit("click")' :ripple='ripple' @contextmenu.prevent="menu = true">
|
||||
<v-list-item-avatar>
|
||||
<v-img :src='track.albumArt.thumb'></v-img>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title
|
||||
:class='{"primary--text": track.id == ($root.track ? $root.track : {id: null}).id}'
|
||||
>{{track.title}}<span v-if='track.explicit' class='red--text text-overline pl-2'>E</span></v-list-item-title>
|
||||
<v-list-item-subtitle>{{track.artistString}}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<!-- Duration -->
|
||||
<div class='text-caption mx-2'>
|
||||
{{$duration(track.duration)}}
|
||||
</div>
|
||||
</v-list-item-action>
|
||||
<v-list-item-action>
|
||||
<!-- Quick add/remoev to library -->
|
||||
<v-btn @click.stop='addLibrary' icon v-if='!isLibrary'>
|
||||
<v-icon>mdi-heart</v-icon>
|
||||
</v-btn>
|
||||
<v-btn @click.stop='removeLibrary' icon v-if='isLibrary'>
|
||||
<v-icon>mdi-heart-remove</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
<v-list-item-action>
|
||||
<!-- Quick add to playlist -->
|
||||
<v-btn @click.stop='popup = true' icon>
|
||||
<v-icon>mdi-playlist-plus</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
<v-list-item-action>
|
||||
<!-- Context menu -->
|
||||
<v-menu v-model='menu' offset-y offset-x absolue>
|
||||
<template v-slot:activator="{on, attrs}">
|
||||
<v-btn v-on='on' v-bind='attrs' icon>
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list dense>
|
||||
<!-- Play Next -->
|
||||
<v-list-item dense @click='playNext'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-playlist-plus</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Play next")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Add to end of queue -->
|
||||
<v-list-item dense @click='addQueue'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-playlist-plus</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Add to queue")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Add to library -->
|
||||
<v-list-item dense @click='addLibrary' v-if='!isLibrary'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-heart</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Add to library")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Remove from library -->
|
||||
<v-list-item dense @click='removeLibrary' v-if='isLibrary'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-heart-remove</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Remove from library")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Add to playlist -->
|
||||
<v-list-item dense @click='popup = true' v-if='!playlistId'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-playlist-plus</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Add to playlist")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Remove from playlist -->
|
||||
<v-list-item dense @click='removePlaylist' v-if='playlistId'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-playlist-remove</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Remove from playlist")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Share -->
|
||||
<v-list-item dense @click='share'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-share-variant</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Share")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Play track mix -->
|
||||
<v-list-item dense @click='trackMix'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-playlist-music</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Play track mix")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Go to album -->
|
||||
<v-list-item dense @click='goAlbum'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-album</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Go to")}} "{{track.album.title}}"</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- Go to artists -->
|
||||
<v-list-item
|
||||
dense
|
||||
@click='goArtist(artist)'
|
||||
v-for="artist in track.artists"
|
||||
:key='"ART" + artist.id'
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-account-music</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Go to")}} "{{artist.name}}"</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Download -->
|
||||
<v-list-item dense @click='download'>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-download</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{$t("Download")}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-list-item-action>
|
||||
|
||||
<!-- Add to playlist dialog -->
|
||||
<v-dialog max-width="400px" v-model='popup'>
|
||||
<PlaylistPopup :track='this.track' @close='popup = false'></PlaylistPopup>
|
||||
</v-dialog>
|
||||
|
||||
<DownloadDialog :tracks='[track]' v-if='downloadDialog' @close='downloadDialog = false'></DownloadDialog>
|
||||
|
||||
</v-list-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PlaylistPopup from '@/components/PlaylistPopup.vue';
|
||||
import DownloadDialog from '@/components/DownloadDialog.vue';
|
||||
|
||||
export default {
|
||||
name: 'TrackTile',
|
||||
components: {
|
||||
PlaylistPopup, DownloadDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
menu: false,
|
||||
popup: false,
|
||||
downloadDialog: false,
|
||||
isLibrary: this.$root.libraryTracks.includes(this.track.id)
|
||||
}
|
||||
},
|
||||
props: {
|
||||
track: Object,
|
||||
//If specified, track can be removed
|
||||
playlistId: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
ripple: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Add track next to queue
|
||||
playNext() {
|
||||
this.$root.addTrackIndex(this.track, this.$root.queue.index+1);
|
||||
},
|
||||
addQueue() {
|
||||
this.$root.queue.data.push(this.track);
|
||||
},
|
||||
addLibrary() {
|
||||
this.isLibrary = true;
|
||||
this.$root.libraryTracks.push(this.track.id);
|
||||
this.$axios.put(`/library/track?id=${this.track.id}`);
|
||||
this.$root.globalSnackbar = this.$t('Added to library!');
|
||||
},
|
||||
goAlbum() {
|
||||
this.$emit('redirect')
|
||||
this.$router.push({
|
||||
path: '/album',
|
||||
query: {album: JSON.stringify(this.track.album)}
|
||||
});
|
||||
},
|
||||
goArtist(a) {
|
||||
this.$emit('redirect');
|
||||
this.$router.push({
|
||||
path: '/artist',
|
||||
query: {artist: JSON.stringify(a)}
|
||||
});
|
||||
},
|
||||
async removeLibrary() {
|
||||
this.isLibrary = false;
|
||||
this.$root.libraryTracks.splice(this.$root.libraryTracks.indexOf(this.track.id), 1);
|
||||
await this.$axios.delete(`/library/track?id=${this.track.id}`);
|
||||
this.$root.globalSnackbar = this.$t('Removed from library!');
|
||||
this.$emit('remove');
|
||||
},
|
||||
//Remove from playlist
|
||||
async removePlaylist() {
|
||||
await this.$axios.delete(`/playlist/${this.playlistId}/tracks`, {
|
||||
data: {track: this.track.id}
|
||||
});
|
||||
this.$root.globalSnackbar = this.$t('Removed from playlist!');
|
||||
this.$emit('remove');
|
||||
},
|
||||
//Download track
|
||||
download() {
|
||||
this.downloadDialog = true;
|
||||
},
|
||||
async trackMix() {
|
||||
let res = await this.$axios.get('/trackmix/' + this.track.id);
|
||||
this.$root.queue.source = {
|
||||
text: this.$t('Track Mix'),
|
||||
source: 'trackmix',
|
||||
data: this.track.id
|
||||
};
|
||||
this.$root.replaceQueue(res.data);
|
||||
this.$root.playIndex(0);
|
||||
},
|
||||
//Copy link
|
||||
share() {
|
||||
let copyElem = document.createElement('input');
|
||||
copyElem.value = `https://deezer.com/track/${this.track.id}`;
|
||||
document.body.appendChild(copyElem);
|
||||
copyElem.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(copyElem);
|
||||
this.$root.globalSnackbar = this.$t('Link copied!');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
23
buildfiles/app/client/src/js/i18n.js
Normal file
@ -0,0 +1,23 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
|
||||
Vue.use(VueI18n);
|
||||
|
||||
function loadLocaleMessages () {
|
||||
const locales = require.context('../locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
|
||||
const messages = {}
|
||||
locales.keys().forEach(key => {
|
||||
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
|
||||
if (matched && matched.length > 1) {
|
||||
const locale = matched[1]
|
||||
messages[locale] = locales(key)
|
||||
}
|
||||
})
|
||||
return messages
|
||||
}
|
||||
|
||||
export default new VueI18n({
|
||||
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
|
||||
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
|
||||
messages: loadLocaleMessages()
|
||||
})
|
91
buildfiles/app/client/src/js/router.js
Normal file
@ -0,0 +1,91 @@
|
||||
import Vue from 'vue';
|
||||
import VueRouter from 'vue-router';
|
||||
|
||||
import Login from '@/views/Login.vue';
|
||||
import HomeScreen from '@/views/HomeScreen.vue';
|
||||
import Search from '@/views/Search.vue';
|
||||
import Library from '@/views/Library.vue';
|
||||
import AlbumPage from '@/views/AlbumPage.vue';
|
||||
import PlaylistPage from '@/views/PlaylistPage.vue';
|
||||
import ArtistPage from '@/views/ArtistPage.vue';
|
||||
import Settings from '@/views/Settings.vue';
|
||||
import DeezerPage from '@/views/DeezerPage.vue';
|
||||
import DownloadsPage from '@/views/DownloadsPage.vue';
|
||||
import About from '@/views/About.vue';
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/home',
|
||||
component: HomeScreen
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
component: Login
|
||||
},
|
||||
{
|
||||
path: '/search',
|
||||
component: Search,
|
||||
props: (route) => {
|
||||
return {query: route.query.q}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/library',
|
||||
component: Library,
|
||||
},
|
||||
//Library short links
|
||||
{path: '/library/tracks', component: Library, props: () => {return {routeTab: 'tracks'}}},
|
||||
{path: '/library/albums', component: Library, props: () => {return {routeTab: 'albums'}}},
|
||||
{path: '/library/artists', component: Library, props: () => {return {routeTab: 'artists'}}},
|
||||
{path: '/library/playlists', component: Library, props: () => {return {routeTab: 'playlists'}}},
|
||||
{
|
||||
path: '/album',
|
||||
component: AlbumPage,
|
||||
props: (route) => {
|
||||
return {albumData: JSON.parse(route.query.album)}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/playlist',
|
||||
component: PlaylistPage,
|
||||
props: (route) => {
|
||||
return {playlistData: JSON.parse(route.query.playlist)}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/artist',
|
||||
component: ArtistPage,
|
||||
props: (route) => {
|
||||
return {artistData: JSON.parse(route.query.artist)}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
component: Settings
|
||||
},
|
||||
{
|
||||
path: '/page',
|
||||
component: DeezerPage,
|
||||
props: (route) => {
|
||||
return {target: route.query.target}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/downloads',
|
||||
component: DownloadsPage,
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
component: About
|
||||
}
|
||||
];
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'hash',
|
||||
base: process.env.BASE_URL,
|
||||
routes
|
||||
});
|
||||
|
||||
export default router;
|
13
buildfiles/app/client/src/js/vuetify.js
Normal file
@ -0,0 +1,13 @@
|
||||
import Vue from 'vue';
|
||||
import Vuetify from 'vuetify/lib';
|
||||
|
||||
import 'roboto-fontface/css/roboto/roboto-fontface.css';
|
||||
import '@mdi/font/css/materialdesignicons.css';
|
||||
|
||||
Vue.use(Vuetify);
|
||||
|
||||
export default new Vuetify({
|
||||
theme: {
|
||||
dark: true
|
||||
}
|
||||
});
|
141
buildfiles/app/client/src/locales/ar.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "القائمة الرئيسية",
|
||||
"Browse": "تصفح",
|
||||
"Library": "المكتبة",
|
||||
"Tracks": "أغاني",
|
||||
"Playlists": "قوائم تشغيل",
|
||||
"Albums": "البومات",
|
||||
"Artists": "فنانون",
|
||||
"More": "المزيد",
|
||||
"Settings": "الإعدادات",
|
||||
"Downloads": "التنزيلات",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "ابحث أو الصق رابط ديزر, استخدم \"/\" للتركيز السريع.",
|
||||
"Play": "تشغيل",
|
||||
"Add to library": "إضافة إلى المكتبة",
|
||||
"Download": "تنزيل",
|
||||
"fans": "المتابِعين",
|
||||
"tracks": "أغاني",
|
||||
"Quality": "الجودة",
|
||||
"Estimated size:": "الحجم المتوقع:",
|
||||
"Start downloading": "بدء التنزيل",
|
||||
"Cancel": "الغاء",
|
||||
"Stream logging is disabled!": "تسجيل البث معطل!",
|
||||
"Enable it in settings for history to work properly.": "فعله في الإعدادات لتفعيل تاريخ السماع بشكل صحيح.",
|
||||
"History": "تاريخ السماع",
|
||||
"Create new playlist": "انشاء قائمة تشغيل جديدة",
|
||||
"TRACKS": "أغاني",
|
||||
"Sort by": "ترتيب حسب",
|
||||
"Date Added": "تاريخ الإضافة",
|
||||
"Name (A-Z)": "الإسم (أ - ي)",
|
||||
"Artist (A-Z)": "الفنان (أ - ي)",
|
||||
"Album (A-Z)": "الألبوم (أ - ي)",
|
||||
"Error loading lyrics or lyrics not found!": "خطأ في تحميل كلمات الاغنية او الكلمات غير موجودة!",
|
||||
"Create playlist": "إنشاء قائمة التشغيل",
|
||||
"Create": "إنشاء",
|
||||
"Add to playlist": "اضافة الى قائمة التشغيل",
|
||||
"Create new": "إنشاء جديد",
|
||||
"Remove": "إزالة",
|
||||
"Play next": "شغل التالي",
|
||||
"Add to queue": "إضافة إلى قائمة الانتظار",
|
||||
"Remove from library": "إزالة من المكتبة",
|
||||
"Remove from playlist": "إزالة من قائمة التشغيل",
|
||||
"Play track mix": "تشغيل مزيج الاغاني",
|
||||
"Go to": "الذهاب الى",
|
||||
"Track Mix": "مزيج الاغاني",
|
||||
"Duration": "المدة",
|
||||
"Released": "تم إصداره",
|
||||
"Disk": "القرص",
|
||||
"albums": "البومات",
|
||||
"Play top": "تشغيل الأفضل",
|
||||
"Radio": "راديو",
|
||||
"Show all albums": "اضهار كل الالبومات",
|
||||
"Show all singles": "إظهار كل الأغاني المنفردة",
|
||||
"Show more": "اظهار المزيد",
|
||||
"Downloaded": "تم التنزيل",
|
||||
"Queue": "قائمة الانتظار",
|
||||
"Total": "المجموع",
|
||||
"Stop": "إيقاف",
|
||||
"Start": "بدء",
|
||||
"Show folder": "عرض المجلدات",
|
||||
"Clear queue": "تفريغ قائمة الإنتظار",
|
||||
"Playing from": "التشغيل من",
|
||||
"Info": "معلومات",
|
||||
"Lyrics": "كلمات الأغنية",
|
||||
"Track number": "رقم الأغنية",
|
||||
"Disk number": "رقم القرص",
|
||||
"Explicit": "صريحة (شتم)",
|
||||
"Source": "المصدر",
|
||||
"ID": "الرقم التعريفي",
|
||||
"Error logging in!": "خطأ في تسجيل الدخول!",
|
||||
"Please try again later, or try another account.": "الرجاء المحاولة مرة أخرى لاحقا، أو حاول حساب آخر.",
|
||||
"Logout": "تسجيل الخروج",
|
||||
"Login using browser": "تسجيل الدخول باستخدام المتصفح",
|
||||
"Please login using your Deezer account:": "يرجى تسجيل الدخول باستخدام حساب ديزر الخاص بك:",
|
||||
"...or paste your ARL/Token below:": "...أو لصق ARL/الرمز الخاص بك أدناه:",
|
||||
"ARL/Token": "ARL/الرمز المميز",
|
||||
"Login": "تسجيل الدخول",
|
||||
"By using this program, you disagree with Deezer's ToS.": "باستخدام هذا البرنامج، أنت لا توافق على شروط خدمة ديزر.",
|
||||
"Only in Electron version!": "فقط في إصدار إلكترون!",
|
||||
"Search results for:": "نتائج البحث عن:",
|
||||
"Error loading data!": "خطأ في تحميل البيانات!",
|
||||
"Try again later!": "حاول مرة اخرى لاحقا!",
|
||||
"Search": "بحث",
|
||||
"Streaming Quality": "جودة التشغيل",
|
||||
"Download Quality": "جودة التنزيل",
|
||||
"Downloads Directory": "مسار التنزيل",
|
||||
"Simultaneous downloads": "عدد التحميلات في نفس الوقت",
|
||||
"Always show download confirm dialog before downloading.": "اضهار مربع تأكيد التنزيل دائماً قبل التنزيل.",
|
||||
"Show download dialog": "عرض مربع تأكيد التنزيل",
|
||||
"Create folders for artists": "إنشاء ملفات للفنان",
|
||||
"Create folders for albums": "إنشاء ملفات للالبوم",
|
||||
"Download lyrics": "تنزيل ملف كلمات الاغنية. Lrc",
|
||||
"Variables": "المتغيرات",
|
||||
"UI": "واجهة المستخدم",
|
||||
"Show autocomplete in search": "إظهار الإكمال التلقائي في البحث",
|
||||
"Integrations": "الدمج",
|
||||
"This allows listening history, flow and recommendations to work properly.": "وهذا يتيح لسجل الاستماع و فلو والتوصيات, العمل على نحو سليم.",
|
||||
"Log track listens to Deezer": "سِجِل استماع الاغاني الى ديزر",
|
||||
"Connect your LastFM account to allow scrobbling.": "قم بتوصيل حساب LastFM الخاص بك للسماح بالتسجيل.",
|
||||
"Login with LastFM": "تسجيل الدخول في LastFM",
|
||||
"Disconnect LastFM": "تسجيل الخروج من LastFm",
|
||||
"Requires restart to apply!": "يتطلب إعادة التشغيل من أجل التطبيق!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "تمكين فعالية دسكورد، يتطلب إعادة تشغيل للتبديل!",
|
||||
"Discord Rich Presence": "فعالية دسكورد",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "تمكين زر انضمام دسكورد لمزامنة الاغاني، يتطلب إعادة تشغيل للتبديل!",
|
||||
"Discord Join Button": "زر الانضمام في دسكورد",
|
||||
"Other": "أخرى",
|
||||
"Minimize to tray": "تصغير إلى شريط المهام",
|
||||
"Don't minimize to tray": "عدم التصغير إلى شريط المهام",
|
||||
"Close on exit": "إغلاق عند الخروج",
|
||||
"Settings saved!": "تم حفظ الإعدادات!",
|
||||
"Available only in Electron version!": "متاح فقط في اصدار الإلكترون!",
|
||||
"Crossfade (ms)": "التلاشي (ملي ثانية)",
|
||||
"Select primary color": "تحديد اللون الأساسي",
|
||||
"Light theme": "المظهر الفاتح",
|
||||
"Create folders for playlists": "إنشاء ملفات لقائمة التشغيل",
|
||||
"About": "حول البرنامج",
|
||||
"Links:": "الروابط:",
|
||||
"Telegram Releases": "إصدارات على تيليجرام",
|
||||
"Telegram Group": "مجموعة التليجرام",
|
||||
"Discord": "دسكورد",
|
||||
"Telegram Android Group": "مجموعة تيليجرام (أندرويد)",
|
||||
"Credits:": "المساهمون:",
|
||||
"Agree": "قبول",
|
||||
"Dismiss": "تجاهل",
|
||||
"Added to playlist!": "تمت الإضافة إلى قائمة التشغيل!",
|
||||
"Added to library!": "تمت الاضافة الى المكتبة!",
|
||||
"Removed from library!": "الإزالة من المكتبة!",
|
||||
"Removed from playlist!": "تمت الإزالة من قائمة التشغيل!",
|
||||
"Playlist deleted!": "تم حذف قائمة التشغيل!",
|
||||
"Delete": "حذف",
|
||||
"Are you sure you want to delete this playlist?": "هل أنت متأكد من أنك تريد حذف قائمة التشغيل هذه؟",
|
||||
"Force white tray icon": "فرض أيقونة شريط المهام البيضاء",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "فرض ايقونة شريط المهام (البيضاء) الافتراضية إذا تم الكشف عن الثيم بشكل غير صحيح. يتطلب إعادة التشغيل.",
|
||||
"Share": "مشاركة",
|
||||
"Settings quality": "جودة الإعدادات",
|
||||
"Content language": "لغة المحتوى",
|
||||
"Content country": "بلد المحتوى",
|
||||
"Website": "الموقع الالكتروني",
|
||||
"Visit website": "زيارة الموقع الإلكتروني",
|
||||
"New update available:": "تحديث جديد متوفر:"
|
||||
}
|
141
buildfiles/app/client/src/locales/cs.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Browse",
|
||||
"Library": "Library",
|
||||
"Tracks": "Tracks",
|
||||
"Playlists": "Playlists",
|
||||
"Albums": "Albums",
|
||||
"Artists": "Artists",
|
||||
"More": "More",
|
||||
"Settings": "Settings",
|
||||
"Downloads": "Downloads",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Search or paste Deezer URL. Use \"/\" to quickly focus.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Add to library",
|
||||
"Download": "Download",
|
||||
"fans": "fans",
|
||||
"tracks": "tracks",
|
||||
"Quality": "Quality",
|
||||
"Estimated size:": "Estimated size:",
|
||||
"Start downloading": "Start downloading",
|
||||
"Cancel": "Cancel",
|
||||
"Stream logging is disabled!": "Stream logging is disabled!",
|
||||
"Enable it in settings for history to work properly.": "Enable it in settings for history to work properly.",
|
||||
"History": "History",
|
||||
"Create new playlist": "Create new playlist",
|
||||
"TRACKS": "TRACKS",
|
||||
"Sort by": "Sort by",
|
||||
"Date Added": "Date Added",
|
||||
"Name (A-Z)": "Name (A-Z)",
|
||||
"Artist (A-Z)": "Artist (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Error loading lyrics or lyrics not found!",
|
||||
"Create playlist": "Create playlist",
|
||||
"Create": "Create",
|
||||
"Add to playlist": "Add to playlist",
|
||||
"Create new": "Create new",
|
||||
"Remove": "Remove",
|
||||
"Play next": "Play next",
|
||||
"Add to queue": "Add to queue",
|
||||
"Remove from library": "Remove from library",
|
||||
"Remove from playlist": "Remove from playlist",
|
||||
"Play track mix": "Play track mix",
|
||||
"Go to": "Go to",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Duration",
|
||||
"Released": "Released",
|
||||
"Disk": "Disk",
|
||||
"albums": "albums",
|
||||
"Play top": "Play top",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Show all albums",
|
||||
"Show all singles": "Show all singles",
|
||||
"Show more": "Show more",
|
||||
"Downloaded": "Downloaded",
|
||||
"Queue": "Queue",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Show folder",
|
||||
"Clear queue": "Clear queue",
|
||||
"Playing from": "Playing from",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lyrics",
|
||||
"Track number": "Track number",
|
||||
"Disk number": "Disk number",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Error logging in!",
|
||||
"Please try again later, or try another account.": "Please try again later, or try another account.",
|
||||
"Logout": "Logout",
|
||||
"Login using browser": "Login using browser",
|
||||
"Please login using your Deezer account:": "Please login using your Deezer account:",
|
||||
"...or paste your ARL/Token below:": "...or paste your ARL/Token below:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "By using this program, you disagree with Deezer's ToS.",
|
||||
"Only in Electron version!": "Only in Electron version!",
|
||||
"Search results for:": "Search results for:",
|
||||
"Error loading data!": "Error loading data!",
|
||||
"Try again later!": "Try again later!",
|
||||
"Search": "Search",
|
||||
"Streaming Quality": "Streaming Quality",
|
||||
"Download Quality": "Download Quality",
|
||||
"Downloads Directory": "Downloads Directory",
|
||||
"Simultaneous downloads": "Simultaneous downloads",
|
||||
"Always show download confirm dialog before downloading.": "Always show download confirm dialog before downloading.",
|
||||
"Show download dialog": "Show download dialog",
|
||||
"Create folders for artists": "Create folders for artists",
|
||||
"Create folders for albums": "Create folders for albums",
|
||||
"Download lyrics": "Download lyrics",
|
||||
"Variables": "Variables",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Show autocomplete in search",
|
||||
"Integrations": "Integrations",
|
||||
"This allows listening history, flow and recommendations to work properly.": "This allows listening history, flow and recommendations to work properly.",
|
||||
"Log track listens to Deezer": "Log track listens to Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Connect your LastFM account to allow scrobbling.",
|
||||
"Login with LastFM": "Login with LastFM",
|
||||
"Disconnect LastFM": "Disconnect LastFM",
|
||||
"Requires restart to apply!": "Requires restart to apply!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Enable Discord Rich Presence, requires restart to toggle!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Enable Discord join button for syncing tracks, requires restart to toggle!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Other",
|
||||
"Minimize to tray": "Minimize to tray",
|
||||
"Don't minimize to tray": "Don't minimize to tray",
|
||||
"Close on exit": "Close on exit",
|
||||
"Settings saved!": "Settings saved!",
|
||||
"Available only in Electron version!": "Available only in Electron version!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Select primary color",
|
||||
"Light theme": "Light theme",
|
||||
"Create folders for playlists": "Create folders for playlists",
|
||||
"About": "About",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram Releases",
|
||||
"Telegram Group": "Telegram Group",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android Group",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Agree",
|
||||
"Dismiss": "Dismiss",
|
||||
"Added to playlist!": "Added to playlist!",
|
||||
"Added to library!": "Added to library!",
|
||||
"Removed from library!": "Removed from library!",
|
||||
"Removed from playlist!": "Removed from playlist!",
|
||||
"Playlist deleted!": "Playlist deleted!",
|
||||
"Delete": "Delete",
|
||||
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?",
|
||||
"Force white tray icon": "Force white tray icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Force default (white) tray icon if theme incorrectly detected. Requires restart.",
|
||||
"Share": "Share",
|
||||
"Settings quality": "Settings quality",
|
||||
"Content language": "Content language",
|
||||
"Content country": "Content country",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/de.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Start",
|
||||
"Browse": "Durchsuchen",
|
||||
"Library": "Mediathek",
|
||||
"Tracks": "Titel",
|
||||
"Playlists": "Wiedergabelisten",
|
||||
"Albums": "Alben",
|
||||
"Artists": "Künstler",
|
||||
"More": "Mehr",
|
||||
"Settings": "Einstellungen",
|
||||
"Downloads": "Downloads",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Suche oder füge Deezer URL ein. Benutze \"/\" um schnell zu fokussieren.",
|
||||
"Play": "Wiedergeben",
|
||||
"Add to library": "Zur Mediathek hinzufügen",
|
||||
"Download": "Download",
|
||||
"fans": "Fans",
|
||||
"tracks": "Titel",
|
||||
"Quality": "Qualität",
|
||||
"Estimated size:": "Geschätzte Zeit:",
|
||||
"Start downloading": "Download beginnen",
|
||||
"Cancel": "Abbrechen",
|
||||
"Stream logging is disabled!": "Streamprotokollierung ist deaktiviert!",
|
||||
"Enable it in settings for history to work properly.": "Aktiviere es in den Einstellungen, damit der Verlauf korrekt funktioniert.",
|
||||
"History": "Verlauf",
|
||||
"Create new playlist": "Neue Playlist erstellen",
|
||||
"TRACKS": "Titel",
|
||||
"Sort by": "Sortieren nach",
|
||||
"Date Added": "Hinzugefügt am",
|
||||
"Name (A-Z)": "Name (A-Z)",
|
||||
"Artist (A-Z)": "Künstler (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Fehler beim Laden der Songtexte oder Songtexte nicht gefunden!",
|
||||
"Create playlist": "Playlist erstellen",
|
||||
"Create": "Erstellen",
|
||||
"Add to playlist": "Zur Playlist hinzufügen",
|
||||
"Create new": "Neu erstellen",
|
||||
"Remove": "Entfernen",
|
||||
"Play next": "Als nächstes spielen",
|
||||
"Add to queue": "Zur Warteschleife hinzufügen",
|
||||
"Remove from library": "Aus der Mediathek entfernen",
|
||||
"Remove from playlist": "Aus Playlist entfernen",
|
||||
"Play track mix": "Track Mix abspielen",
|
||||
"Go to": "Gehe zu",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Dauer",
|
||||
"Released": "Veröffentlicht",
|
||||
"Disk": "Disk",
|
||||
"albums": "Alben",
|
||||
"Play top": "Top abspielen",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Zeige alle Alben",
|
||||
"Show all singles": "Zeige alle Singles",
|
||||
"Show more": "Mehr anzeigen",
|
||||
"Downloaded": "Heruntergeladen",
|
||||
"Queue": "Warteschleife",
|
||||
"Total": "Gesamt",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Ordner anzeigen",
|
||||
"Clear queue": "Warteschleife löschen",
|
||||
"Playing from": "Wiedergabe von",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lyrics",
|
||||
"Track number": "Titelnummer",
|
||||
"Disk number": "Disk-Nummer",
|
||||
"Explicit": "Explizit",
|
||||
"Source": "Quelle",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Fehler beim einloggen!",
|
||||
"Please try again later, or try another account.": "Bitte versuche es später noch einmal oder versuche es mit einem anderen Konto.",
|
||||
"Logout": "Abmelden",
|
||||
"Login using browser": "Anmeldung über Browser",
|
||||
"Please login using your Deezer account:": "Bitte melde dich mit deinem Deezer-Konto an:",
|
||||
"...or paste your ARL/Token below:": "...oder füge dein ARL/Token unten ein:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Anmeldung",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Durch die Verwendung dieses Programms lehnen Sie Deezer's ToS ab.",
|
||||
"Only in Electron version!": "Nur in der Electron-Version!",
|
||||
"Search results for:": "Suchergebnisse für:",
|
||||
"Error loading data!": "Fehler beim Laden der Daten!",
|
||||
"Try again later!": "Versuch's später nochmal!",
|
||||
"Search": "Suche",
|
||||
"Streaming Quality": "Streamqualität",
|
||||
"Download Quality": "Download-Qualität",
|
||||
"Downloads Directory": "Downloadverzeichnis",
|
||||
"Simultaneous downloads": "Gleichzeitige Downloads",
|
||||
"Always show download confirm dialog before downloading.": "Downloadbestätigungsdialog immer vor dem Download anzeigen.",
|
||||
"Show download dialog": "Download-Dialog anzeigen",
|
||||
"Create folders for artists": "Ordner für Künstler erstellen",
|
||||
"Create folders for albums": "Ordner für Alben erstellen",
|
||||
"Download lyrics": "Download Lyrics",
|
||||
"Variables": "Variablen",
|
||||
"UI": "Benutzeroberfläche",
|
||||
"Show autocomplete in search": "Auto-Vervollständigung in der Suche anzeigen",
|
||||
"Integrations": "Integrationen",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Dies ermöglicht das korrekte Arbeiten von Wiedergabeverlauf, Flow und Empfehlungen.",
|
||||
"Log track listens to Deezer": "Prokotolliere gehörte Titel auf Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Verbinde dein LastFM-Konto, um das Scrobbing zu erlauben.",
|
||||
"Login with LastFM": "Anmelden mit LastFM",
|
||||
"Disconnect LastFM": "Disconnect LastFM",
|
||||
"Requires restart to apply!": "Erfordert einen Neustart der App!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Discord Rich Presence aktivieren, erfordert einen Neustart zum Umschalten!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Aktiviere Discord Join für die Synchronisierung von Titel, benötigt einen Neustart zum Umschalten!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Andere",
|
||||
"Minimize to tray": "In Statusleiste minimieren",
|
||||
"Don't minimize to tray": "Nicht in Statusleiste minimieren",
|
||||
"Close on exit": "Beim Beenden schließen",
|
||||
"Settings saved!": "Einstellungen gespeichert!",
|
||||
"Available only in Electron version!": "Nur in der Electron-Version verfügbar!",
|
||||
"Crossfade (ms)": "Überblendung (ms)",
|
||||
"Select primary color": "Primärfarbe auswählen",
|
||||
"Light theme": "Helles Thema",
|
||||
"Create folders for playlists": "Ordner für Wiedergabelisten erstellen",
|
||||
"About": "Über",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram-Releases",
|
||||
"Telegram Group": "Telegram Gruppe",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android-Gruppe",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Einverstanden",
|
||||
"Dismiss": "Verwerfen",
|
||||
"Added to playlist!": "Zur Wiedergabeliste hinzugefügt!",
|
||||
"Added to library!": "Zur Mediathek hinzufügen!",
|
||||
"Removed from library!": "Aus der Mediathek entfernen!",
|
||||
"Removed from playlist!": "Aus der Wiedergabeliste entfernt!",
|
||||
"Playlist deleted!": "Wiedergabeliste gelöscht!",
|
||||
"Delete": "Löschen",
|
||||
"Are you sure you want to delete this playlist?": "Bist du sicher, dass du diese Wiedergabeliste löschen willst?",
|
||||
"Force white tray icon": "Erzwinge weißes Tray-Icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Standardsymbol (weiß) in der Kontrollleiste erzwingen, wenn Design falsch erkannt wurde. Neustart erforderlich.",
|
||||
"Share": "Teilen",
|
||||
"Settings quality": "Audioqualität-Einstellungen",
|
||||
"Content language": "Sprache des Inhalts",
|
||||
"Content country": "Land des Inhalts",
|
||||
"Website": "Webseite",
|
||||
"Visit website": "Webseite besuchen",
|
||||
"New update available:": "Neues Update verfügbar:"
|
||||
}
|
141
buildfiles/app/client/src/locales/el.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Αρχική",
|
||||
"Browse": "Περιήγηση",
|
||||
"Library": "Βιβλιοθήκη",
|
||||
"Tracks": "Κομμάτια",
|
||||
"Playlists": "Λίστες αναπαραγωγής",
|
||||
"Albums": "Album",
|
||||
"Artists": "Καλλιτέχνες",
|
||||
"More": "Περισσότερα",
|
||||
"Settings": "Ρυθμίσεις",
|
||||
"Downloads": "Λήψεις",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Αναζήτηση ή επικόλληση διεύθυνσης URL Deezer. Χρησιμοποιήστε το \"/\" για γρήγορη εστίαση.",
|
||||
"Play": "Αναπαραγωγή",
|
||||
"Add to library": "Προσθήκη στη βιβλιοθήκη",
|
||||
"Download": "Λήψη",
|
||||
"fans": "θαυμαστές",
|
||||
"tracks": "κομμάτια",
|
||||
"Quality": "Ποιότητα",
|
||||
"Estimated size:": "Εκτιμώμενος χρόνος:",
|
||||
"Start downloading": "Έναρξη λήψης",
|
||||
"Cancel": "Άκυρο",
|
||||
"Stream logging is disabled!": "Η καταγραφή ροής είναι ανενεργή!",
|
||||
"Enable it in settings for history to work properly.": "Ενεργοποιήστε το στις ρυθμίσεις για την σωστή λειτουργία του ιστορικού.",
|
||||
"History": "Ιστορικό",
|
||||
"Create new playlist": "Δημιουργία λίστας αναπαραγωγής",
|
||||
"TRACKS": "ΤΡΑΓΟΥΔΙΑ",
|
||||
"Sort by": "Ταξινόμηση κατά",
|
||||
"Date Added": "Ημερομηνία Προσθήκης",
|
||||
"Name (A-Z)": "Όνομα (Α-Ω)",
|
||||
"Artist (A-Z)": "Καλλιτέχνης (Α-Ω)",
|
||||
"Album (A-Z)": "Album (Α-Ω)",
|
||||
"Error loading lyrics or lyrics not found!": "Σφάλμα κατά τη φόρτωση στίχων ή αδυναμία εύρεσης στίχων!",
|
||||
"Create playlist": "Δημιουργία λίστας αναπαραγωγής",
|
||||
"Create": "Δημιουργία",
|
||||
"Add to playlist": "Προσθήκη στην λίστα αναπαραγωγής",
|
||||
"Create new": "Δημιουργία νέου",
|
||||
"Remove": "Αφαίρεση",
|
||||
"Play next": "Παίξε αμέσως μετά",
|
||||
"Add to queue": "Προσθήκη στην ουρά",
|
||||
"Remove from library": "Κατάργηση από τη βιβλιοθήκη",
|
||||
"Remove from playlist": "Κατάργηση από τη λίστα αναπαραγωγής",
|
||||
"Play track mix": "Αναπαραγωγή μίξης τραγουδιών",
|
||||
"Go to": "Πήγαινε σε",
|
||||
"Track Mix": "Μίξη Τραγουδιών",
|
||||
"Duration": "Διάρκεια",
|
||||
"Released": "Κυκλοφόρησε",
|
||||
"Disk": "Δίσκος",
|
||||
"albums": "album",
|
||||
"Play top": "Αναπαραγωγή κορυφαίου",
|
||||
"Radio": "Ραδιόφωνο",
|
||||
"Show all albums": "Εμφάνιση όλων των album",
|
||||
"Show all singles": "Εμφάνιση όλων των single",
|
||||
"Show more": "Εμφάνιση περισσότερων",
|
||||
"Downloaded": "Ελήφθησαν",
|
||||
"Queue": "Ουρά",
|
||||
"Total": "Σύνολο ",
|
||||
"Stop": "Διακοπή",
|
||||
"Start": "Έναρξη",
|
||||
"Show folder": "Εμφάνιση φακέλου",
|
||||
"Clear queue": "Εκκαθάριση ουράς",
|
||||
"Playing from": "Αναπαραγωγή από",
|
||||
"Info": "Πληροφορίες",
|
||||
"Lyrics": "Στίχοι",
|
||||
"Track number": "Αριθμός τραγουδιού",
|
||||
"Disk number": "Αριθμός δίσκου",
|
||||
"Explicit": "Άσεμνο περιεχόμενο",
|
||||
"Source": "Πηγή",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Σφάλμα εισόδου!",
|
||||
"Please try again later, or try another account.": "Δοκιμάστε ξανά αργότερα ή δοκιμάστε έναν άλλο λογαριασμό.",
|
||||
"Logout": "Αποσύνδεση",
|
||||
"Login using browser": "Σύνδεση χρησιμοποιώντας το πρόγραμμα περιήγησης",
|
||||
"Please login using your Deezer account:": "Συνδεθείτε χρησιμοποιώντας τον λογαριασμό σας στο Deezer:",
|
||||
"...or paste your ARL/Token below:": "... ή επικολλήστε το ARL/Token σας παρακάτω:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Σύνδεση",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Χρησιμοποιώντας αυτό το πρόγραμμα, διαφωνείτε με τους όρους χρήσης του Deezer.",
|
||||
"Only in Electron version!": "Μόνο στην έκδοση Electron!",
|
||||
"Search results for:": "Αποτελέσματα αναζήτησης για:",
|
||||
"Error loading data!": "Σφάλμα φόρτωσης δεδομένων!",
|
||||
"Try again later!": "Δοκιμάστε ξανά αργότερα!",
|
||||
"Search": "Αναζήτηση",
|
||||
"Streaming Quality": "Ποιότητα ροής",
|
||||
"Download Quality": "Ποιότητα λήψης",
|
||||
"Downloads Directory": "Κατάλογος Λήψεων",
|
||||
"Simultaneous downloads": "Ταυτόχρονες λήψεις",
|
||||
"Always show download confirm dialog before downloading.": "Να εμφανίζεται πάντα το παράθυρο διαλόγου επιβεβαίωσης πριν από τη λήψη.",
|
||||
"Show download dialog": "Εμφάνιση παραθύρου διαλόγου επιβεβαίωσης",
|
||||
"Create folders for artists": "Δημιουργία φακέλου για καλλιτέχνη",
|
||||
"Create folders for albums": "Δημιουργία φακέλων για album",
|
||||
"Download lyrics": "Λήψη στίχων",
|
||||
"Variables": "Μεταβλητές",
|
||||
"UI": "Περιβάλλον Χρήστη",
|
||||
"Show autocomplete in search": "Εμφάνιση αυτόματων συμπληρώσεων στην αναζήτηση",
|
||||
"Integrations": "Ενσωματώσεις",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Επιτρέπει στο ιστορικό ακρόασης, το flow και τις προτάσεις να λειτουργούν σωστά.",
|
||||
"Log track listens to Deezer": "Καταγραφή ακρόασης κομματιών στο Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Συνδέστε τον λογαριασμό σας LastFM για να επιτρέψετε το scrobbling.",
|
||||
"Login with LastFM": "Σύνδεση με LastFM",
|
||||
"Disconnect LastFM": "Αποσύνδεση από LastFM",
|
||||
"Requires restart to apply!": "Απαιτείται επανεκκίνηση για την εφαρμογή!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Ενεργοποίηση Discord Rich Presence, απαιτείται επανεκκίνηση!",
|
||||
"Discord Rich Presence": "Ενεργοποίηση Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Ενεργοποιήστε το κουμπί συμμετοχής Discord για συγχρονισμό κομματιών, απαιτείται επανεκκίνηση!",
|
||||
"Discord Join Button": "Κουμπί συμμετοχής Discord",
|
||||
"Other": "Άλλα",
|
||||
"Minimize to tray": "Ελαχιστοποίηση σε εικονίδιο",
|
||||
"Don't minimize to tray": "Μην ελαχιστοποιείτε σε εικονίδιο",
|
||||
"Close on exit": "Κλείσιμο κατά την έξοδο",
|
||||
"Settings saved!": "Οι ρυθμίσεις αποθηκεύτηκαν!",
|
||||
"Available only in Electron version!": "Διαθέσιμο μόνο στην έκδοση Electron!",
|
||||
"Crossfade (ms)": "Μίξη ομαλής μετάβασης (ms)",
|
||||
"Select primary color": "Επιλογή κύριου χρώματος",
|
||||
"Light theme": "Φωτεινό θέμα",
|
||||
"Create folders for playlists": "Δημιουργία φακέλων για λίστες αναπαραγωγής",
|
||||
"About": "Σχετικά",
|
||||
"Links:": "Σύνδεσμοι:",
|
||||
"Telegram Releases": "Κυκλοφορίες Telegram",
|
||||
"Telegram Group": "Ομάδα Telegram",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Ομάδα Android Telegram",
|
||||
"Credits:": "Συντελεστές:",
|
||||
"Agree": "Αποδοχή",
|
||||
"Dismiss": "Απόρριψη",
|
||||
"Added to playlist!": "Προστέθηκε σε λίστα αναπαραγωγής!",
|
||||
"Added to library!": "Προστέθηκε στη βιβλιοθήκη!",
|
||||
"Removed from library!": "Καταργήθηκε από τη βιβλιοθήκη!",
|
||||
"Removed from playlist!": "Καταργήθηκε από τη λίστα αναπαραγωγής!",
|
||||
"Playlist deleted!": "Η λίστα αναπαραγωγής διαγράφηκε!",
|
||||
"Delete": "Διαγραφή",
|
||||
"Are you sure you want to delete this playlist?": "Είστε βέβαιοι ότι θέλετε να διαγράψετε την λίστα αναπαραγωγής;",
|
||||
"Force white tray icon": "Εξαναγκασμός λευκού εικονιδίου",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Επαναφορά προεπιλογής (λευκού) εικονιδίου σε περίπτωση σφάλματος θέματος. Απαιτείται επανεκκίνηση.",
|
||||
"Share": "Κοινοποίηση",
|
||||
"Settings quality": "Επιλογή ρυθμίσεων ποιότητας",
|
||||
"Content language": "Γλώσσα περιεχομένου",
|
||||
"Content country": "Χώρα περιεχομένου",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/en.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Browse",
|
||||
"Library": "Library",
|
||||
"Tracks": "Tracks",
|
||||
"Playlists": "Playlists",
|
||||
"Albums": "Albums",
|
||||
"Artists": "Artists",
|
||||
"More": "More",
|
||||
"Settings": "Settings",
|
||||
"Downloads": "Downloads",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Search or paste Deezer URL. Use \"/\" to quickly focus.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Add to library",
|
||||
"Download": "Download",
|
||||
"fans": "fans",
|
||||
"tracks": "tracks",
|
||||
"Quality": "Quality",
|
||||
"Estimated size:": "Estimated size:",
|
||||
"Start downloading": "Start downloading",
|
||||
"Cancel": "Cancel",
|
||||
"Stream logging is disabled!": "Stream logging is disabled!",
|
||||
"Enable it in settings for history to work properly.": "Enable it in settings for history to work properly.",
|
||||
"History": "History",
|
||||
"Create new playlist": "Create new playlist",
|
||||
"TRACKS": "TRACKS",
|
||||
"Sort by": "Sort by",
|
||||
"Date Added": "Date Added",
|
||||
"Name (A-Z)": "Name (A-Z)",
|
||||
"Artist (A-Z)": "Artist (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Error loading lyrics or lyrics not found!",
|
||||
"Create playlist": "Create playlist",
|
||||
"Create": "Create",
|
||||
"Add to playlist": "Add to playlist",
|
||||
"Create new": "Create new",
|
||||
"Remove": "Remove",
|
||||
"Play next": "Play next",
|
||||
"Add to queue": "Add to queue",
|
||||
"Remove from library": "Remove from library",
|
||||
"Remove from playlist": "Remove from playlist",
|
||||
"Play track mix": "Play track mix",
|
||||
"Go to": "Go to",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Duration",
|
||||
"Released": "Released",
|
||||
"Disk": "Disk",
|
||||
"albums": "albums",
|
||||
"Play top": "Play top",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Show all albums",
|
||||
"Show all singles": "Show all singles",
|
||||
"Show more": "Show more",
|
||||
"Downloaded": "Downloaded",
|
||||
"Queue": "Queue",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Show folder",
|
||||
"Clear queue": "Clear queue",
|
||||
"Playing from": "Playing from",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lyrics",
|
||||
"Track number": "Track number",
|
||||
"Disk number": "Disk number",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Error logging in!",
|
||||
"Please try again later, or try another account.": "Please try again later, or try another account.",
|
||||
"Logout": "Logout",
|
||||
"Login using browser": "Login using browser",
|
||||
"Please login using your Deezer account:": "Please login using your Deezer account:",
|
||||
"...or paste your ARL/Token below:": "...or paste your ARL/Token below:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "By using this program, you disagree with Deezer's ToS.",
|
||||
"Only in Electron version!": "Only in Electron version!",
|
||||
"Search results for:": "Search results for:",
|
||||
"Error loading data!": "Error loading data!",
|
||||
"Try again later!": "Try again later!",
|
||||
"Search": "Search",
|
||||
"Streaming Quality": "Streaming Quality",
|
||||
"Download Quality": "Download Quality",
|
||||
"Downloads Directory": "Downloads Directory",
|
||||
"Simultaneous downloads": "Simultaneous downloads",
|
||||
"Always show download confirm dialog before downloading.": "Always show download confirm dialog before downloading.",
|
||||
"Show download dialog": "Show download dialog",
|
||||
"Create folders for artists": "Create folders for artists",
|
||||
"Create folders for albums": "Create folders for albums",
|
||||
"Download lyrics": "Download lyrics",
|
||||
"Variables": "Variables",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Show autocomplete in search",
|
||||
"Integrations": "Integrations",
|
||||
"This allows listening history, flow and recommendations to work properly.": "This allows listening history, flow and recommendations to work properly.",
|
||||
"Log track listens to Deezer": "Log track listens to Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Connect your LastFM account to allow scrobbling.",
|
||||
"Login with LastFM": "Login with LastFM",
|
||||
"Disconnect LastFM": "Disconnect LastFM",
|
||||
"Requires restart to apply!": "Requires restart to apply!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Enable Discord Rich Presence, requires restart to toggle!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Enable Discord join button for syncing tracks, requires restart to toggle!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Other",
|
||||
"Minimize to tray": "Minimize to tray",
|
||||
"Don't minimize to tray": "Don't minimize to tray",
|
||||
"Close on exit": "Close on exit",
|
||||
"Settings saved!": "Settings saved!",
|
||||
"Available only in Electron version!": "Available only in Electron version!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Select primary color",
|
||||
"Light theme": "Light theme",
|
||||
"Create folders for playlists": "Create folders for playlists",
|
||||
"About": "About",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram Releases",
|
||||
"Telegram Group": "Telegram Group",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android Group",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Agree",
|
||||
"Dismiss": "Dismiss",
|
||||
"Added to playlist!": "Added to playlist!",
|
||||
"Added to library!": "Added to library!",
|
||||
"Removed from library!": "Removed from library!",
|
||||
"Removed from playlist!": "Removed from playlist!",
|
||||
"Playlist deleted!": "Playlist deleted!",
|
||||
"Delete": "Delete",
|
||||
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?",
|
||||
"Force white tray icon": "Force white tray icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Force default (white) tray icon if theme incorrectly detected. Requires restart.",
|
||||
"Share": "Share",
|
||||
"Settings quality": "Settings quality",
|
||||
"Content language": "Content language",
|
||||
"Content country": "Content country",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/es.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Inicio",
|
||||
"Browse": "Explorar",
|
||||
"Library": "Biblioteca",
|
||||
"Tracks": "Pistas",
|
||||
"Playlists": "Listas de reproducción",
|
||||
"Albums": "Álbumes",
|
||||
"Artists": "Artistas",
|
||||
"More": "Más",
|
||||
"Settings": "Ajustes",
|
||||
"Downloads": "Descargas",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Busca o pega la URL de Deezer. Usa \"/\" para empezar a buscar.",
|
||||
"Play": "Reproducir",
|
||||
"Add to library": "Añadir a la biblioteca",
|
||||
"Download": "Descargar",
|
||||
"fans": "seguidores",
|
||||
"tracks": "pistas",
|
||||
"Quality": "Calidad",
|
||||
"Estimated size:": "Tamaño estimado:",
|
||||
"Start downloading": "Comenzar descarga",
|
||||
"Cancel": "Cancelar",
|
||||
"Stream logging is disabled!": "¡El registro de reproducción está deshabilitado!",
|
||||
"Enable it in settings for history to work properly.": "Habilítalo en los ajustes para que el historial funcione correctamente.",
|
||||
"History": "Historial",
|
||||
"Create new playlist": "Crear nueva lista de reproducción",
|
||||
"TRACKS": "PISTAS",
|
||||
"Sort by": "Ordenar por",
|
||||
"Date Added": "Fecha de adición",
|
||||
"Name (A-Z)": "Nombre (A-Z)",
|
||||
"Artist (A-Z)": "Artista (A-Z)",
|
||||
"Album (A-Z)": "Álbum (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "¡Error al cargar letras o no encontradas!",
|
||||
"Create playlist": "Crear lista de reproducción",
|
||||
"Create": "Crear",
|
||||
"Add to playlist": "Agregar a la lista de reproducción",
|
||||
"Create new": "Crear nuevo",
|
||||
"Remove": "Quitar",
|
||||
"Play next": "Reproducir siguiente",
|
||||
"Add to queue": "Añadir a la cola de reproducción",
|
||||
"Remove from library": "Eliminar de la biblioteca",
|
||||
"Remove from playlist": "Quitar de la lista de reproducción",
|
||||
"Play track mix": "Reproducir mezcla de canciones",
|
||||
"Go to": "Ir a",
|
||||
"Track Mix": "Mezcla de canciones",
|
||||
"Duration": "Duración",
|
||||
"Released": "Publicado",
|
||||
"Disk": "Disco",
|
||||
"albums": "álbumes",
|
||||
"Play top": "Reproducir top",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Mostrar todos los álbumes",
|
||||
"Show all singles": "Mostrar todos los singles",
|
||||
"Show more": "Mostrar más",
|
||||
"Downloaded": "Descargadas",
|
||||
"Queue": "Cola",
|
||||
"Total": "Total",
|
||||
"Stop": "Parar",
|
||||
"Start": "Iniciar",
|
||||
"Show folder": "Mostrar carpeta",
|
||||
"Clear queue": "Limpiar lista",
|
||||
"Playing from": "Reproduciendo desde",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Letras",
|
||||
"Track number": "Número de la canción",
|
||||
"Disk number": "Número del disco",
|
||||
"Explicit": "Explícito",
|
||||
"Source": "Fuente",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "¡Error al iniciar sesión!",
|
||||
"Please try again later, or try another account.": "Por favor, inténtalo de nuevo más tarde, o prueba con otra cuenta.",
|
||||
"Logout": "Cerrar sesión",
|
||||
"Login using browser": "Iniciar sesión con navegador",
|
||||
"Please login using your Deezer account:": "Por favor, inicia sesión con tu cuenta de Deezer:",
|
||||
"...or paste your ARL/Token below:": "...o pega tu ARL/Token a continuación:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Iniciar sesión",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Al usar este programa, usted no está de acuerdo con los Términos de Servicio de Deezer.",
|
||||
"Only in Electron version!": "¡Sólo en la versión Electron!",
|
||||
"Search results for:": "Resultados de la búsqueda para:",
|
||||
"Error loading data!": "¡Error al cargar datos!",
|
||||
"Try again later!": "¡Inténtalo más tarde!",
|
||||
"Search": "Buscar",
|
||||
"Streaming Quality": "Calidad de reproducción",
|
||||
"Download Quality": "Calidad de descarga",
|
||||
"Downloads Directory": "Carpeta de descargas",
|
||||
"Simultaneous downloads": "Descargas simultaneas máximas",
|
||||
"Always show download confirm dialog before downloading.": "Mostrar siempre una confirmación de descarga antes de descargar.",
|
||||
"Show download dialog": "Mostrar diálogo de descargas",
|
||||
"Create folders for artists": "Crear carpetas por artistas",
|
||||
"Create folders for albums": "Crear carpetas por álbumes",
|
||||
"Download lyrics": "Descargar letras",
|
||||
"Variables": "Variables",
|
||||
"UI": "Interfaz de Usuario",
|
||||
"Show autocomplete in search": "Mostrar autocompletado al buscar",
|
||||
"Integrations": "Integraciones",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Esto permite registrar el historial, para que flow y las recomendaciones funcionen correctamente.",
|
||||
"Log track listens to Deezer": "Enviar registro de reproducción a Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Conecta tu cuenta de LastFM para permitir sincronizar tus canciones.",
|
||||
"Login with LastFM": "Iniciar sesión con LastFM",
|
||||
"Disconnect LastFM": "Desconectar LastFM",
|
||||
"Requires restart to apply!": "¡Requiere reiniciar para aplicar!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "¡Activar Rich Presence de Discord requiere reiniciar para cambiar!",
|
||||
"Discord Rich Presence": "Rich Presence de Discord",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Activar el botón de unión de Discord para sincronizar las canciones, ¡requiere reiniciar para cambiarlo!",
|
||||
"Discord Join Button": "Botón Unirse en Discord",
|
||||
"Other": "Otro",
|
||||
"Minimize to tray": "Minimizar a la bandeja del sistema",
|
||||
"Don't minimize to tray": "No minimizar a la bandeja del sistema",
|
||||
"Close on exit": "Cerrar al salir",
|
||||
"Settings saved!": "¡Configuraciones guardadas!",
|
||||
"Available only in Electron version!": "¡Disponible sólo en la versión Electron!",
|
||||
"Crossfade (ms)": "Transición (ms)",
|
||||
"Select primary color": "Seleccionar color primario",
|
||||
"Light theme": "Tema claro",
|
||||
"Create folders for playlists": "Crear carpetas para listas de reproducción",
|
||||
"About": "Acerca de",
|
||||
"Links:": "Enlaces:",
|
||||
"Telegram Releases": "Lanzamientos en Telegram",
|
||||
"Telegram Group": "Grupo en Telegram",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Grupo de Android en Telegram",
|
||||
"Credits:": "Créditos:",
|
||||
"Agree": "Acepto",
|
||||
"Dismiss": "Descartar",
|
||||
"Added to playlist!": "¡Añadido a la lista de reproducción!",
|
||||
"Added to library!": "¡Agregado a la biblioteca!",
|
||||
"Removed from library!": "¡Eliminado de la biblioteca!",
|
||||
"Removed from playlist!": "¡Eliminado de la lista de reproducción!",
|
||||
"Playlist deleted!": "¡Lista de reproducción eliminada!",
|
||||
"Delete": "Eliminar",
|
||||
"Are you sure you want to delete this playlist?": "¿Está seguro de querer eliminar la lista de reproducción?",
|
||||
"Force white tray icon": "Forzar icono blanco en la bandeja",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Forzar icono predeterminado en bandeja (blanco) si el tema no es detectado correctamente. Requiere reinicio.",
|
||||
"Share": "Compartir",
|
||||
"Settings quality": "Ajustes de calidad",
|
||||
"Content language": "Idioma del contenido",
|
||||
"Content country": "País del contenido",
|
||||
"Website": "Sitio Web",
|
||||
"Visit website": "Visita la página web",
|
||||
"New update available:": "Nueva actualización disponible:"
|
||||
}
|
141
buildfiles/app/client/src/locales/fa.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Browse",
|
||||
"Library": "Library",
|
||||
"Tracks": "Tracks",
|
||||
"Playlists": "Playlists",
|
||||
"Albums": "Albums",
|
||||
"Artists": "Artists",
|
||||
"More": "More",
|
||||
"Settings": "Settings",
|
||||
"Downloads": "Downloads",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Search or paste Deezer URL. Use \"/\" to quickly focus.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Add to library",
|
||||
"Download": "Download",
|
||||
"fans": "fans",
|
||||
"tracks": "tracks",
|
||||
"Quality": "Quality",
|
||||
"Estimated size:": "Estimated size:",
|
||||
"Start downloading": "Start downloading",
|
||||
"Cancel": "Cancel",
|
||||
"Stream logging is disabled!": "Stream logging is disabled!",
|
||||
"Enable it in settings for history to work properly.": "Enable it in settings for history to work properly.",
|
||||
"History": "History",
|
||||
"Create new playlist": "Create new playlist",
|
||||
"TRACKS": "TRACKS",
|
||||
"Sort by": "Sort by",
|
||||
"Date Added": "Date Added",
|
||||
"Name (A-Z)": "Name (A-Z)",
|
||||
"Artist (A-Z)": "Artist (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Error loading lyrics or lyrics not found!",
|
||||
"Create playlist": "Create playlist",
|
||||
"Create": "Create",
|
||||
"Add to playlist": "Add to playlist",
|
||||
"Create new": "Create new",
|
||||
"Remove": "Remove",
|
||||
"Play next": "Play next",
|
||||
"Add to queue": "Add to queue",
|
||||
"Remove from library": "Remove from library",
|
||||
"Remove from playlist": "Remove from playlist",
|
||||
"Play track mix": "Play track mix",
|
||||
"Go to": "Go to",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Duration",
|
||||
"Released": "Released",
|
||||
"Disk": "Disk",
|
||||
"albums": "albums",
|
||||
"Play top": "Play top",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Show all albums",
|
||||
"Show all singles": "Show all singles",
|
||||
"Show more": "Show more",
|
||||
"Downloaded": "Downloaded",
|
||||
"Queue": "Queue",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Show folder",
|
||||
"Clear queue": "Clear queue",
|
||||
"Playing from": "Playing from",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lyrics",
|
||||
"Track number": "Track number",
|
||||
"Disk number": "Disk number",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Error logging in!",
|
||||
"Please try again later, or try another account.": "Please try again later, or try another account.",
|
||||
"Logout": "Logout",
|
||||
"Login using browser": "Login using browser",
|
||||
"Please login using your Deezer account:": "Please login using your Deezer account:",
|
||||
"...or paste your ARL/Token below:": "...or paste your ARL/Token below:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "By using this program, you disagree with Deezer's ToS.",
|
||||
"Only in Electron version!": "Only in Electron version!",
|
||||
"Search results for:": "Search results for:",
|
||||
"Error loading data!": "Error loading data!",
|
||||
"Try again later!": "Try again later!",
|
||||
"Search": "Search",
|
||||
"Streaming Quality": "Streaming Quality",
|
||||
"Download Quality": "Download Quality",
|
||||
"Downloads Directory": "Downloads Directory",
|
||||
"Simultaneous downloads": "Simultaneous downloads",
|
||||
"Always show download confirm dialog before downloading.": "Always show download confirm dialog before downloading.",
|
||||
"Show download dialog": "Show download dialog",
|
||||
"Create folders for artists": "Create folders for artists",
|
||||
"Create folders for albums": "Create folders for albums",
|
||||
"Download lyrics": "Download lyrics",
|
||||
"Variables": "Variables",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Show autocomplete in search",
|
||||
"Integrations": "Integrations",
|
||||
"This allows listening history, flow and recommendations to work properly.": "This allows listening history, flow and recommendations to work properly.",
|
||||
"Log track listens to Deezer": "Log track listens to Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Connect your LastFM account to allow scrobbling.",
|
||||
"Login with LastFM": "Login with LastFM",
|
||||
"Disconnect LastFM": "Disconnect LastFM",
|
||||
"Requires restart to apply!": "Requires restart to apply!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Enable Discord Rich Presence, requires restart to toggle!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Enable Discord join button for syncing tracks, requires restart to toggle!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Other",
|
||||
"Minimize to tray": "Minimize to tray",
|
||||
"Don't minimize to tray": "Don't minimize to tray",
|
||||
"Close on exit": "Close on exit",
|
||||
"Settings saved!": "Settings saved!",
|
||||
"Available only in Electron version!": "Available only in Electron version!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Select primary color",
|
||||
"Light theme": "Light theme",
|
||||
"Create folders for playlists": "Create folders for playlists",
|
||||
"About": "About",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram Releases",
|
||||
"Telegram Group": "Telegram Group",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android Group",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Agree",
|
||||
"Dismiss": "Dismiss",
|
||||
"Added to playlist!": "Added to playlist!",
|
||||
"Added to library!": "Added to library!",
|
||||
"Removed from library!": "Removed from library!",
|
||||
"Removed from playlist!": "Removed from playlist!",
|
||||
"Playlist deleted!": "Playlist deleted!",
|
||||
"Delete": "Delete",
|
||||
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?",
|
||||
"Force white tray icon": "Force white tray icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Force default (white) tray icon if theme incorrectly detected. Requires restart.",
|
||||
"Share": "Share",
|
||||
"Settings quality": "Settings quality",
|
||||
"Content language": "Content language",
|
||||
"Content country": "Content country",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/fil.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Browse",
|
||||
"Library": "Library",
|
||||
"Tracks": "Mga kanta",
|
||||
"Playlists": "Mga playlist",
|
||||
"Albums": "Mga album",
|
||||
"Artists": "Mga artista",
|
||||
"More": "More",
|
||||
"Settings": "Settings",
|
||||
"Downloads": "Mga download",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Search or paste Deezer URL. Use \"/\" to quickly focus.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Idagdag sa library",
|
||||
"Download": "I-download",
|
||||
"fans": "fans",
|
||||
"tracks": "mga kanta",
|
||||
"Quality": "Kalidad",
|
||||
"Estimated size:": "Tinantyang laki:",
|
||||
"Start downloading": "Simulan ang download",
|
||||
"Cancel": "I-kansel",
|
||||
"Stream logging is disabled!": "Naka-disable ang stream logging!",
|
||||
"Enable it in settings for history to work properly.": "Enable it in settings for history to work properly.",
|
||||
"History": "History",
|
||||
"Create new playlist": "Gumawa ng bagong playlist",
|
||||
"TRACKS": "TRACKS",
|
||||
"Sort by": "Sort by",
|
||||
"Date Added": "Petsa kung kailan idinagdag",
|
||||
"Name (A-Z)": "Name (A-Z)",
|
||||
"Artist (A-Z)": "Artista (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Error loading lyrics or lyrics not found!",
|
||||
"Create playlist": "Gumawa ng playlist",
|
||||
"Create": "Gumawa",
|
||||
"Add to playlist": "Idagdag sa playlist",
|
||||
"Create new": "Gumawa ng bago",
|
||||
"Remove": "Tanggalin",
|
||||
"Play next": "I-play ang kasunod",
|
||||
"Add to queue": "Idagdag sa queue",
|
||||
"Remove from library": "Tanggalin sa library",
|
||||
"Remove from playlist": "Tanggalin mula sa playlist",
|
||||
"Play track mix": "Play track mix",
|
||||
"Go to": "Pumunta sa",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Duration",
|
||||
"Released": "Released",
|
||||
"Disk": "Disk",
|
||||
"albums": "Mga album",
|
||||
"Play top": "Play top",
|
||||
"Radio": "Radyo",
|
||||
"Show all albums": "Ipakita lahat ng album",
|
||||
"Show all singles": "Ipakita ang lahat ng mga single",
|
||||
"Show more": "Show more",
|
||||
"Downloaded": "Mga na-download",
|
||||
"Queue": "Queue",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Show folder",
|
||||
"Clear queue": "Clear queue",
|
||||
"Playing from": "Playing from",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Liriko",
|
||||
"Track number": "Track number",
|
||||
"Disk number": "Disk number",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Error logging in!",
|
||||
"Please try again later, or try another account.": "Paki-subukan ulit mamaya, o mag-try ng ibang account.",
|
||||
"Logout": "Mag-logout",
|
||||
"Login using browser": "Mag-login gamit ang browser",
|
||||
"Please login using your Deezer account:": "Paki-login ang iyong Deezer account:",
|
||||
"...or paste your ARL/Token below:": "...o ilagay ang iyong ARL/Token sa baba:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Mag-login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Sa paggamit ng program na ito, ikaw ay hindi sumasang-ayon sa ToS ng Deezer.",
|
||||
"Only in Electron version!": "Sa Electron version lamang!",
|
||||
"Search results for:": "Maghanap ng resulta para sa:",
|
||||
"Error loading data!": "May problema habang naglo-load ng mga datos!",
|
||||
"Try again later!": "Paki-subukan ulit mamaya!",
|
||||
"Search": "Maghanap",
|
||||
"Streaming Quality": "Kalidad ng streaming",
|
||||
"Download Quality": "Kalidad ng download",
|
||||
"Downloads Directory": "Lalagyan ng mga download",
|
||||
"Simultaneous downloads": "Sabay-sabay na download",
|
||||
"Always show download confirm dialog before downloading.": "Laging ipakita ang confirm dialog bago mag-download.",
|
||||
"Show download dialog": "Ipakita ang download dialog",
|
||||
"Create folders for artists": "Gumawa ng folder para sa mga artista",
|
||||
"Create folders for albums": "Gumawa ng folder para sa mga album",
|
||||
"Download lyrics": "I-download ang lyrics",
|
||||
"Variables": "Mga variable",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Ipakita ang autocomplete sa search",
|
||||
"Integrations": "Mga integration",
|
||||
"This allows listening history, flow and recommendations to work properly.": "This allows listening history, flow and recommendations to work properly.",
|
||||
"Log track listens to Deezer": "Log track listens to Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Ikabit ang iyong LastFM account para sa scrobbling.",
|
||||
"Login with LastFM": "Mag-login gamit ang LastFM",
|
||||
"Disconnect LastFM": "Tanggalin ang LastFM",
|
||||
"Requires restart to apply!": "Kailangan i-restart para ma-apply!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "I-enable ang Discord Rich Presence, kailangan i-restart para mabago!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "I-enable ang Discord join button para sa pag-sync ng mga kanta, kailangan i-restart para mabago!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Iba pa",
|
||||
"Minimize to tray": "I-minimize sa tray",
|
||||
"Don't minimize to tray": "Huwag i-minimize sa tray",
|
||||
"Close on exit": "Isara sa pag-pindot ng X",
|
||||
"Settings saved!": "Na-save ang settings!",
|
||||
"Available only in Electron version!": "Meron lamang sa Electron version!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Pumili ng pangunahing kulay",
|
||||
"Light theme": "Maliwanag na tema",
|
||||
"Create folders for playlists": "Gumawa ng folder para sa mga playlist",
|
||||
"About": "About",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram Releases",
|
||||
"Telegram Group": "Grupo sa Telegram",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android Group",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Agree",
|
||||
"Dismiss": "Dismiss",
|
||||
"Added to playlist!": "Added to playlist!",
|
||||
"Added to library!": "Added to library!",
|
||||
"Removed from library!": "Removed from library!",
|
||||
"Removed from playlist!": "Removed from playlist!",
|
||||
"Playlist deleted!": "Playlist deleted!",
|
||||
"Delete": "Delete",
|
||||
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?",
|
||||
"Force white tray icon": "Force white tray icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Force default (white) tray icon if theme incorrectly detected. Requires restart.",
|
||||
"Share": "Ibahagi",
|
||||
"Settings quality": "Settings quality",
|
||||
"Content language": "Wika ng nilalaman",
|
||||
"Content country": "Bansa ng nilalaman",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/fr.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Accueil",
|
||||
"Browse": "Explorer",
|
||||
"Library": "Bibliothèque",
|
||||
"Tracks": "Titres",
|
||||
"Playlists": "Playlists",
|
||||
"Albums": "Albums",
|
||||
"Artists": "Artistes",
|
||||
"More": "Plus",
|
||||
"Settings": "Paramètres",
|
||||
"Downloads": "Téléchargements",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Recherchez ou collez une URL Deezer. Utilisez \"/\" pour lancer rapidement la recherche.",
|
||||
"Play": "Lire",
|
||||
"Add to library": "Ajouter à la bibliothèque",
|
||||
"Download": "Télécharger",
|
||||
"fans": "fans",
|
||||
"tracks": "titres",
|
||||
"Quality": "Qualité",
|
||||
"Estimated size:": "Durée estimée:",
|
||||
"Start downloading": "Lancer le téléchargement",
|
||||
"Cancel": "Annuler",
|
||||
"Stream logging is disabled!": "La journalisation du stream est désactivée !",
|
||||
"Enable it in settings for history to work properly.": "Activez-le dans les paramètres pour que l'historique fonctionne correctement.",
|
||||
"History": "Historique",
|
||||
"Create new playlist": "Créer une nouvelle playlist",
|
||||
"TRACKS": "TITRES",
|
||||
"Sort by": "Trier par",
|
||||
"Date Added": "Ajouté le",
|
||||
"Name (A-Z)": "Nom (A-Z)",
|
||||
"Artist (A-Z)": "Artiste (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Erreur lors du chargement des paroles ou paroles introuvables !",
|
||||
"Create playlist": "Créer une playlist",
|
||||
"Create": "Créer",
|
||||
"Add to playlist": "Ajouter à une playlist",
|
||||
"Create new": "Créer un nouveau",
|
||||
"Remove": "Supprimer",
|
||||
"Play next": "Lire juste après",
|
||||
"Add to queue": "Ajouter à la file d'attente",
|
||||
"Remove from library": "Supprimer de la bibliothèque",
|
||||
"Remove from playlist": "Supprimer de la playlist",
|
||||
"Play track mix": "Jouer un mélange de titres",
|
||||
"Go to": "Aller à",
|
||||
"Track Mix": "Mélange de titres",
|
||||
"Duration": "Durée",
|
||||
"Released": "Publié",
|
||||
"Disk": "Disque",
|
||||
"albums": "albums",
|
||||
"Play top": "Lire en haut",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Afficher tous les albums",
|
||||
"Show all singles": "Afficher tous les singles",
|
||||
"Show more": "Afficher plus",
|
||||
"Downloaded": "Téléchargés",
|
||||
"Queue": "File d'attente",
|
||||
"Total": "Total",
|
||||
"Stop": "Arrêter",
|
||||
"Start": "Lancer",
|
||||
"Show folder": "Afficher le dossier",
|
||||
"Clear queue": "Effacer la liste d'attente",
|
||||
"Playing from": "Lecture depuis",
|
||||
"Info": "Infos",
|
||||
"Lyrics": "Paroles",
|
||||
"Track number": "Numéro de piste",
|
||||
"Disk number": "Numéro de disque",
|
||||
"Explicit": "Explicite",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Erreur de connexion !",
|
||||
"Please try again later, or try another account.": "Veuillez réessayer plus tard, ou essayez avec un autre compte.",
|
||||
"Logout": "Déconnexion",
|
||||
"Login using browser": "Connexion via navigateur",
|
||||
"Please login using your Deezer account:": "Veuillez vous connecter en utilisant votre compte Deezer:",
|
||||
"...or paste your ARL/Token below:": "...ou copiez votre ARL/Token ici:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Connexion",
|
||||
"By using this program, you disagree with Deezer's ToS.": "En utilisant ce programme, vous désagréez avec les conditions générales d'utilisation et de vente de Deezer.",
|
||||
"Only in Electron version!": "Uniquement en version Electron !",
|
||||
"Search results for:": "Résultats de la recherche pour:",
|
||||
"Error loading data!": "Erreur lors du chargement des données !",
|
||||
"Try again later!": "Réessayez plus tard !",
|
||||
"Search": "Recherche",
|
||||
"Streaming Quality": "Qualité en streaming",
|
||||
"Download Quality": "Qualité de téléchargement",
|
||||
"Downloads Directory": "Chemin de sauvegarde",
|
||||
"Simultaneous downloads": "Limite téléchargements simultanés",
|
||||
"Always show download confirm dialog before downloading.": "Toujours afficher une boîte de dialogue pour confirmer le téléchargement avant de le commencer.",
|
||||
"Show download dialog": "Afficher une boîte de dialogue pour chaque téléchargement",
|
||||
"Create folders for artists": "Générer des dossiers par artiste",
|
||||
"Create folders for albums": "Générer des dossiers par album",
|
||||
"Download lyrics": "Télécharger les paroles",
|
||||
"Variables": "Variables",
|
||||
"UI": "Interface",
|
||||
"Show autocomplete in search": "Afficher la saisie automatique dans la recherche",
|
||||
"Integrations": "Intégrations",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Cela permet à l'historique des titres écoutés, au flow et aux recommandations de fonctionner correctement.",
|
||||
"Log track listens to Deezer": "Journaliser sur Deezer les titres écoutés",
|
||||
"Connect your LastFM account to allow scrobbling.": "Connectez votre compte LastFM pour autoriser le scrobbling.",
|
||||
"Login with LastFM": "Se connecter avec LastFM",
|
||||
"Disconnect LastFM": "Déconnecté LastFM",
|
||||
"Requires restart to apply!": "Redémarrage nécessaire pour prendre effet !",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Activer la présence Discord, nécessite un redémarrage pour prendre effet !",
|
||||
"Discord Rich Presence": "Présence sur Discord",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Activer le bouton \"rejoindre\" sur Discord pour synchroniser les titres, nécessite un redémarrage pour prendre effet !",
|
||||
"Discord Join Button": "Bouton rejoindre sur Discord",
|
||||
"Other": "Autre",
|
||||
"Minimize to tray": "Réduire dans la zone de notification",
|
||||
"Don't minimize to tray": "Ne pas réduire dans la zone de notification",
|
||||
"Close on exit": "Fermer en quittant",
|
||||
"Settings saved!": "Paramètres sauvegardés !",
|
||||
"Available only in Electron version!": "Uniquement disponible en version Electron !",
|
||||
"Crossfade (ms)": "Fondu enchaîné (ms)",
|
||||
"Select primary color": "Sélectionner la couleur principale",
|
||||
"Light theme": "Thème clair",
|
||||
"Create folders for playlists": "Créer des dossiers par playlist",
|
||||
"About": "À propos",
|
||||
"Links:": "Liens:",
|
||||
"Telegram Releases": "Publications Telegram",
|
||||
"Telegram Group": "Groupe Telegram",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Groupe Telegram Android",
|
||||
"Credits:": "Crédits:",
|
||||
"Agree": "Accepter",
|
||||
"Dismiss": "Cacher",
|
||||
"Added to playlist!": "Ajouté à la playlist !",
|
||||
"Added to library!": "Ajouté à la bibliothèque !",
|
||||
"Removed from library!": "Supprimé de la bibliothèque !",
|
||||
"Removed from playlist!": "Supprimé de la playlist !",
|
||||
"Playlist deleted!": "Playlist supprimée !",
|
||||
"Delete": "Supprimer",
|
||||
"Are you sure you want to delete this playlist?": "Voulez-vous vraiment supprimer cette liste de lecture ?",
|
||||
"Force white tray icon": "Forcer l'icône blanche dans la zone de notification",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Forcer l'icône blanche par défaut dans la zone de notification si le thème n'est pas correctement détecté. Nécessite un redémarrage.",
|
||||
"Share": "Partager",
|
||||
"Settings quality": "Qualité définie dans les paramètres",
|
||||
"Content language": "Langue du contenu",
|
||||
"Content country": "Pays du contenu",
|
||||
"Website": "Site internet",
|
||||
"Visit website": "Visiter le site internet",
|
||||
"New update available:": "Nouvelle mise à jour disponible :"
|
||||
}
|
141
buildfiles/app/client/src/locales/he.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Browse",
|
||||
"Library": "Library",
|
||||
"Tracks": "Tracks",
|
||||
"Playlists": "Playlists",
|
||||
"Albums": "Albums",
|
||||
"Artists": "Artists",
|
||||
"More": "More",
|
||||
"Settings": "Settings",
|
||||
"Downloads": "Downloads",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Search or paste Deezer URL. Use \"/\" to quickly focus.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Add to library",
|
||||
"Download": "Download",
|
||||
"fans": "fans",
|
||||
"tracks": "tracks",
|
||||
"Quality": "Quality",
|
||||
"Estimated size:": "Estimated size:",
|
||||
"Start downloading": "Start downloading",
|
||||
"Cancel": "Cancel",
|
||||
"Stream logging is disabled!": "Stream logging is disabled!",
|
||||
"Enable it in settings for history to work properly.": "Enable it in settings for history to work properly.",
|
||||
"History": "History",
|
||||
"Create new playlist": "Create new playlist",
|
||||
"TRACKS": "TRACKS",
|
||||
"Sort by": "Sort by",
|
||||
"Date Added": "Date Added",
|
||||
"Name (A-Z)": "Name (A-Z)",
|
||||
"Artist (A-Z)": "Artist (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Error loading lyrics or lyrics not found!",
|
||||
"Create playlist": "Create playlist",
|
||||
"Create": "Create",
|
||||
"Add to playlist": "Add to playlist",
|
||||
"Create new": "Create new",
|
||||
"Remove": "Remove",
|
||||
"Play next": "Play next",
|
||||
"Add to queue": "Add to queue",
|
||||
"Remove from library": "Remove from library",
|
||||
"Remove from playlist": "Remove from playlist",
|
||||
"Play track mix": "Play track mix",
|
||||
"Go to": "Go to",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Duration",
|
||||
"Released": "Released",
|
||||
"Disk": "Disk",
|
||||
"albums": "albums",
|
||||
"Play top": "Play top",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Show all albums",
|
||||
"Show all singles": "Show all singles",
|
||||
"Show more": "Show more",
|
||||
"Downloaded": "Downloaded",
|
||||
"Queue": "Queue",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Show folder",
|
||||
"Clear queue": "Clear queue",
|
||||
"Playing from": "Playing from",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lyrics",
|
||||
"Track number": "Track number",
|
||||
"Disk number": "Disk number",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Error logging in!",
|
||||
"Please try again later, or try another account.": "Please try again later, or try another account.",
|
||||
"Logout": "Logout",
|
||||
"Login using browser": "Login using browser",
|
||||
"Please login using your Deezer account:": "Please login using your Deezer account:",
|
||||
"...or paste your ARL/Token below:": "...or paste your ARL/Token below:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "By using this program, you disagree with Deezer's ToS.",
|
||||
"Only in Electron version!": "Only in Electron version!",
|
||||
"Search results for:": "Search results for:",
|
||||
"Error loading data!": "Error loading data!",
|
||||
"Try again later!": "Try again later!",
|
||||
"Search": "Search",
|
||||
"Streaming Quality": "Streaming Quality",
|
||||
"Download Quality": "Download Quality",
|
||||
"Downloads Directory": "Downloads Directory",
|
||||
"Simultaneous downloads": "Simultaneous downloads",
|
||||
"Always show download confirm dialog before downloading.": "Always show download confirm dialog before downloading.",
|
||||
"Show download dialog": "Show download dialog",
|
||||
"Create folders for artists": "Create folders for artists",
|
||||
"Create folders for albums": "Create folders for albums",
|
||||
"Download lyrics": "Download lyrics",
|
||||
"Variables": "Variables",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Show autocomplete in search",
|
||||
"Integrations": "Integrations",
|
||||
"This allows listening history, flow and recommendations to work properly.": "This allows listening history, flow and recommendations to work properly.",
|
||||
"Log track listens to Deezer": "Log track listens to Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Connect your LastFM account to allow scrobbling.",
|
||||
"Login with LastFM": "Login with LastFM",
|
||||
"Disconnect LastFM": "Disconnect LastFM",
|
||||
"Requires restart to apply!": "Requires restart to apply!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Enable Discord Rich Presence, requires restart to toggle!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Enable Discord join button for syncing tracks, requires restart to toggle!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Other",
|
||||
"Minimize to tray": "Minimize to tray",
|
||||
"Don't minimize to tray": "Don't minimize to tray",
|
||||
"Close on exit": "Close on exit",
|
||||
"Settings saved!": "Settings saved!",
|
||||
"Available only in Electron version!": "Available only in Electron version!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Select primary color",
|
||||
"Light theme": "Light theme",
|
||||
"Create folders for playlists": "Create folders for playlists",
|
||||
"About": "About",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram Releases",
|
||||
"Telegram Group": "Telegram Group",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android Group",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Agree",
|
||||
"Dismiss": "Dismiss",
|
||||
"Added to playlist!": "Added to playlist!",
|
||||
"Added to library!": "Added to library!",
|
||||
"Removed from library!": "Removed from library!",
|
||||
"Removed from playlist!": "Removed from playlist!",
|
||||
"Playlist deleted!": "Playlist deleted!",
|
||||
"Delete": "Delete",
|
||||
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?",
|
||||
"Force white tray icon": "Force white tray icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Force default (white) tray icon if theme incorrectly detected. Requires restart.",
|
||||
"Share": "Share",
|
||||
"Settings quality": "Settings quality",
|
||||
"Content language": "Content language",
|
||||
"Content country": "Content country",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/hi.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Browse",
|
||||
"Library": "Library",
|
||||
"Tracks": "Tracks",
|
||||
"Playlists": "Playlists",
|
||||
"Albums": "Albums",
|
||||
"Artists": "Artists",
|
||||
"More": "More",
|
||||
"Settings": "Settings",
|
||||
"Downloads": "Downloads",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Search or paste Deezer URL. Use \"/\" to quickly focus.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Add to library",
|
||||
"Download": "Download",
|
||||
"fans": "fans",
|
||||
"tracks": "tracks",
|
||||
"Quality": "Quality",
|
||||
"Estimated size:": "Estimated size:",
|
||||
"Start downloading": "Start downloading",
|
||||
"Cancel": "Cancel",
|
||||
"Stream logging is disabled!": "Stream logging is disabled!",
|
||||
"Enable it in settings for history to work properly.": "Enable it in settings for history to work properly.",
|
||||
"History": "History",
|
||||
"Create new playlist": "Create new playlist",
|
||||
"TRACKS": "TRACKS",
|
||||
"Sort by": "Sort by",
|
||||
"Date Added": "Date Added",
|
||||
"Name (A-Z)": "Name (A-Z)",
|
||||
"Artist (A-Z)": "Artist (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Error loading lyrics or lyrics not found!",
|
||||
"Create playlist": "Create playlist",
|
||||
"Create": "Create",
|
||||
"Add to playlist": "Add to playlist",
|
||||
"Create new": "Create new",
|
||||
"Remove": "Remove",
|
||||
"Play next": "Play next",
|
||||
"Add to queue": "Add to queue",
|
||||
"Remove from library": "Remove from library",
|
||||
"Remove from playlist": "Remove from playlist",
|
||||
"Play track mix": "Play track mix",
|
||||
"Go to": "Go to",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Duration",
|
||||
"Released": "Released",
|
||||
"Disk": "Disk",
|
||||
"albums": "albums",
|
||||
"Play top": "Play top",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Show all albums",
|
||||
"Show all singles": "Show all singles",
|
||||
"Show more": "Show more",
|
||||
"Downloaded": "Downloaded",
|
||||
"Queue": "Queue",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Show folder",
|
||||
"Clear queue": "Clear queue",
|
||||
"Playing from": "Playing from",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lyrics",
|
||||
"Track number": "Track number",
|
||||
"Disk number": "Disk number",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Error logging in!",
|
||||
"Please try again later, or try another account.": "Please try again later, or try another account.",
|
||||
"Logout": "Logout",
|
||||
"Login using browser": "Login using browser",
|
||||
"Please login using your Deezer account:": "Please login using your Deezer account:",
|
||||
"...or paste your ARL/Token below:": "...or paste your ARL/Token below:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "By using this program, you disagree with Deezer's ToS.",
|
||||
"Only in Electron version!": "Only in Electron version!",
|
||||
"Search results for:": "Search results for:",
|
||||
"Error loading data!": "Error loading data!",
|
||||
"Try again later!": "Try again later!",
|
||||
"Search": "Search",
|
||||
"Streaming Quality": "Streaming Quality",
|
||||
"Download Quality": "Download Quality",
|
||||
"Downloads Directory": "Downloads Directory",
|
||||
"Simultaneous downloads": "Simultaneous downloads",
|
||||
"Always show download confirm dialog before downloading.": "Always show download confirm dialog before downloading.",
|
||||
"Show download dialog": "Show download dialog",
|
||||
"Create folders for artists": "Create folders for artists",
|
||||
"Create folders for albums": "Create folders for albums",
|
||||
"Download lyrics": "Download lyrics",
|
||||
"Variables": "Variables",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Show autocomplete in search",
|
||||
"Integrations": "Integrations",
|
||||
"This allows listening history, flow and recommendations to work properly.": "This allows listening history, flow and recommendations to work properly.",
|
||||
"Log track listens to Deezer": "Log track listens to Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Connect your LastFM account to allow scrobbling.",
|
||||
"Login with LastFM": "Login with LastFM",
|
||||
"Disconnect LastFM": "Disconnect LastFM",
|
||||
"Requires restart to apply!": "Requires restart to apply!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Enable Discord Rich Presence, requires restart to toggle!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Enable Discord join button for syncing tracks, requires restart to toggle!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Other",
|
||||
"Minimize to tray": "Minimize to tray",
|
||||
"Don't minimize to tray": "Don't minimize to tray",
|
||||
"Close on exit": "Close on exit",
|
||||
"Settings saved!": "Settings saved!",
|
||||
"Available only in Electron version!": "Available only in Electron version!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Select primary color",
|
||||
"Light theme": "Light theme",
|
||||
"Create folders for playlists": "Create folders for playlists",
|
||||
"About": "About",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram Releases",
|
||||
"Telegram Group": "Telegram Group",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android Group",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Agree",
|
||||
"Dismiss": "Dismiss",
|
||||
"Added to playlist!": "Added to playlist!",
|
||||
"Added to library!": "Added to library!",
|
||||
"Removed from library!": "Removed from library!",
|
||||
"Removed from playlist!": "Removed from playlist!",
|
||||
"Playlist deleted!": "Playlist deleted!",
|
||||
"Delete": "Delete",
|
||||
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?",
|
||||
"Force white tray icon": "Force white tray icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Force default (white) tray icon if theme incorrectly detected. Requires restart.",
|
||||
"Share": "Share",
|
||||
"Settings quality": "Settings quality",
|
||||
"Content language": "Content language",
|
||||
"Content country": "Content country",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/hr.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Početna",
|
||||
"Browse": "Pretraži",
|
||||
"Library": "Biblioteka",
|
||||
"Tracks": "Pjesme",
|
||||
"Playlists": "Popisi za reprodukciju",
|
||||
"Albums": "Albumi",
|
||||
"Artists": "Izvođači",
|
||||
"More": "Više",
|
||||
"Settings": "Postavke",
|
||||
"Downloads": "Preuzimanja",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Pretražite ili kopirajte Deezer URL. Koristite \"/\" za brzo fokusiranje.",
|
||||
"Play": "Reproduciraj",
|
||||
"Add to library": "Dodaj u biblioteku",
|
||||
"Download": "Preuzmi",
|
||||
"fans": "obožavatelji",
|
||||
"tracks": "pjesme",
|
||||
"Quality": "Kvaliteta",
|
||||
"Estimated size:": "Predviđena veličina:",
|
||||
"Start downloading": "Započni preuzimanje",
|
||||
"Cancel": "Poništi",
|
||||
"Stream logging is disabled!": "Bilježenje strujanja je onemogućeno!",
|
||||
"Enable it in settings for history to work properly.": "Uključite u postavkama kako bi povijest funkcionirala normalno.",
|
||||
"History": "Povijest",
|
||||
"Create new playlist": "Kreirajte novi popis za reprodukciju",
|
||||
"TRACKS": "PJESME",
|
||||
"Sort by": "Sortiraj po",
|
||||
"Date Added": "Datum dodavanja",
|
||||
"Name (A-Z)": "Naziv (A-Z)",
|
||||
"Artist (A-Z)": "Izvođač (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Pogreška kod učitavanja tekstova pjesme ili tekstovi pjesme nisu pronađeni!",
|
||||
"Create playlist": "Napravi popis za reprodukciju",
|
||||
"Create": "Stvori",
|
||||
"Add to playlist": "Dodaj u popis za reprodukciju",
|
||||
"Create new": "Stvori novi",
|
||||
"Remove": "Ukloni",
|
||||
"Play next": "Reproduciraj sljedeće",
|
||||
"Add to queue": "Dodaj u red",
|
||||
"Remove from library": "Ukloni iz biblioteke",
|
||||
"Remove from playlist": "Ukloni iz popisa za reprodukciju",
|
||||
"Play track mix": "Sviraj miks pjesme",
|
||||
"Go to": "Idi u",
|
||||
"Track Mix": "Miks pjesme",
|
||||
"Duration": "Trajanje",
|
||||
"Released": "Objavljeno",
|
||||
"Disk": "Disk",
|
||||
"albums": "albumi",
|
||||
"Play top": "Sviraj najpopularnije",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Prikaži sve albume",
|
||||
"Show all singles": "Pokaži sve singlove",
|
||||
"Show more": "Pokaži više",
|
||||
"Downloaded": "Preuzeto",
|
||||
"Queue": "Red",
|
||||
"Total": "Ukupno",
|
||||
"Stop": "Zaustavi",
|
||||
"Start": "Započni",
|
||||
"Show folder": "Pokaži mapu",
|
||||
"Clear queue": "Očisti red",
|
||||
"Playing from": "Svira iz",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Tekst pjesme",
|
||||
"Track number": "Broj pjesme",
|
||||
"Disk number": "Broj diska",
|
||||
"Explicit": "Eksplicitno",
|
||||
"Source": "Izvor",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Pogreška prilikom prijavljivanja!",
|
||||
"Please try again later, or try another account.": "Molimo pokušajte ponovno kasnije ili pokušajte sa drugim računom.",
|
||||
"Logout": "Odjava",
|
||||
"Login using browser": "Prijava pomoću preglednika",
|
||||
"Please login using your Deezer account:": "Molimo vas da se prijavite pomoću vašeg Deezer računa:",
|
||||
"...or paste your ARL/Token below:": "...ili zalijepite svoj ARL/Token ispod:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Prijava",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Korištenjem ovog programa, ne prihvaćate Deezerove Uvjete pružanja usluge.",
|
||||
"Only in Electron version!": "Samo u Electron verziji!",
|
||||
"Search results for:": "Rezultati pretrage za:",
|
||||
"Error loading data!": "Greška pri učitavanju podataka!",
|
||||
"Try again later!": "Pokušajte ponovno kasnije!",
|
||||
"Search": "Pretraga",
|
||||
"Streaming Quality": "Kvaliteta strujanja",
|
||||
"Download Quality": "Kvaliteta preuzimanja",
|
||||
"Downloads Directory": "Direktorij preuzimanja",
|
||||
"Simultaneous downloads": "Istovremena preuzimanja",
|
||||
"Always show download confirm dialog before downloading.": "Uvijek prikaži dijaloški okvir potvrde prije preuzimanja.",
|
||||
"Show download dialog": "Prikaži dijalog za preuzimanje",
|
||||
"Create folders for artists": "Napravi mape za izvođače",
|
||||
"Create folders for albums": "Naprave mape za albume",
|
||||
"Download lyrics": "Preuzmi tekstove pjesama",
|
||||
"Variables": "Varijable",
|
||||
"UI": "Korisničko sučelje",
|
||||
"Show autocomplete in search": "Pokaži samodovršavanje u pretrazi",
|
||||
"Integrations": "Integracije",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Ovo omogućava da povijest slušanja, flow i preporuke rade ispravno.",
|
||||
"Log track listens to Deezer": "Bilježi slušanje pjesama prema Deezeru",
|
||||
"Connect your LastFM account to allow scrobbling.": "Spojite svoj LastFM račun da biste omogućili skroblanje.",
|
||||
"Login with LastFM": "Prijavite se sa LastFM",
|
||||
"Disconnect LastFM": "Odspojite LastFM",
|
||||
"Requires restart to apply!": "Zahtjeva ponovno pokretanje da bi se primijenilo!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Omogući Obogaćeno Discord Prisustvo, zahtijeva ponovno pokretanje kako biste mogli prebaciti!",
|
||||
"Discord Rich Presence": "Obogaćeno Discord Prisutstvo",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Omogući gumb Discord pridruživanje za sinkroniziranje pjesama, zahtijeva ponovno pokretanje kako biste mogli prebaciti!",
|
||||
"Discord Join Button": "Gumb Discord pridruživanje",
|
||||
"Other": "Ostalo",
|
||||
"Minimize to tray": "Umanjite na alatnu traku",
|
||||
"Don't minimize to tray": "Nemoj umanjiti na alatnu traku",
|
||||
"Close on exit": "Zatvori na izlasku",
|
||||
"Settings saved!": "Postavke spremljene!",
|
||||
"Available only in Electron version!": "Dostupno samo u Electron verziji!",
|
||||
"Crossfade (ms)": "Utišavanje/pretapanje (ms)",
|
||||
"Select primary color": "Izaberi primarnu boju",
|
||||
"Light theme": "Svijetla tema",
|
||||
"Create folders for playlists": "Stvori mape za popise za reprodukciju",
|
||||
"About": "O aplikaciji",
|
||||
"Links:": "Poveznice:",
|
||||
"Telegram Releases": "Telegram izdanja",
|
||||
"Telegram Group": "Telegram grupa",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android grupa",
|
||||
"Credits:": "Zasluge:",
|
||||
"Agree": "Slažem se",
|
||||
"Dismiss": "Odbaci",
|
||||
"Added to playlist!": "Dodano u popis za reprodukciju!",
|
||||
"Added to library!": "Dodano u biblioteku!",
|
||||
"Removed from library!": "Uklonjeno iz biblioteke!",
|
||||
"Removed from playlist!": "Uklonjeno iz popisa za reprodukciju!",
|
||||
"Playlist deleted!": "Popis za reprodukciju izbrisan!",
|
||||
"Delete": "Izbriši",
|
||||
"Are you sure you want to delete this playlist?": "Jeste li sigurni da želite izbrisati ovaj popis za reprodukciju?",
|
||||
"Force white tray icon": "Prisili bijelu ikonu u alatnoj traci",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Prisili zadanu (bijelu) ikonu alatne trake ako je tema neispravno detektirana. Zahtijeva ponovno pokretanje.",
|
||||
"Share": "Podijeli",
|
||||
"Settings quality": "Postavke kvalitete",
|
||||
"Content language": "Jezik sadržaja",
|
||||
"Content country": "Zemlja sadržaja",
|
||||
"Website": "Web stranica",
|
||||
"Visit website": "Posjeti web-stranicu",
|
||||
"New update available:": "Dostupno je novo ažuriranje:"
|
||||
}
|
141
buildfiles/app/client/src/locales/hu.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Kezdőlap",
|
||||
"Browse": "Böngészés",
|
||||
"Library": "Könyvtár",
|
||||
"Tracks": "Dalok",
|
||||
"Playlists": "Lejátszási listák",
|
||||
"Albums": "Albumok",
|
||||
"Artists": "Előadók",
|
||||
"More": "Továbbiak",
|
||||
"Settings": "Beállítások",
|
||||
"Downloads": "Letöltések",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Keressen, vagy illesszen be Deezer URL linket. Használja a \"/\" karaktert, hogy gyorsan ősszpontosítson.",
|
||||
"Play": "Lejátszás",
|
||||
"Add to library": "Hozzáadás a könyvtárhoz",
|
||||
"Download": "Letöltés",
|
||||
"fans": "rajongók",
|
||||
"tracks": "dalok",
|
||||
"Quality": "Minőség",
|
||||
"Estimated size:": "Becsült fájl méret:",
|
||||
"Start downloading": "Letöltés indítása",
|
||||
"Cancel": "Mégse",
|
||||
"Stream logging is disabled!": "Stream naplózás le van tiltva!",
|
||||
"Enable it in settings for history to work properly.": "Engedélyezze a beállításokban, hogy az előzmények megfelelően működjenek.",
|
||||
"History": "Előzmények",
|
||||
"Create new playlist": "Új lejátszási lista létrehozása",
|
||||
"TRACKS": "DALOK",
|
||||
"Sort by": "Rendezési elv",
|
||||
"Date Added": "Hozzáadás dátuma",
|
||||
"Name (A-Z)": "Név (A-Z)",
|
||||
"Artist (A-Z)": "Előadó (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Hiba a dalszöveg betöltésekor, vagy nem található dalszöveg!",
|
||||
"Create playlist": "Lejátszási lista létrehozása",
|
||||
"Create": "Létrehozás",
|
||||
"Add to playlist": "Hozzáadás a lejátszási listához",
|
||||
"Create new": "Új létrehozása",
|
||||
"Remove": "Eltávolítás",
|
||||
"Play next": "Következő lejátszása",
|
||||
"Add to queue": "Hozzáadás a várólistához",
|
||||
"Remove from library": "Eltávolítás a könyvtárból",
|
||||
"Remove from playlist": "Eltávolítás a lejátszási listáról",
|
||||
"Play track mix": "Play track mix",
|
||||
"Go to": "Go to",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Duration",
|
||||
"Released": "Released",
|
||||
"Disk": "Disk",
|
||||
"albums": "albums",
|
||||
"Play top": "Play top",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Show all albums",
|
||||
"Show all singles": "Show all singles",
|
||||
"Show more": "Show more",
|
||||
"Downloaded": "Downloaded",
|
||||
"Queue": "Queue",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Show folder",
|
||||
"Clear queue": "Clear queue",
|
||||
"Playing from": "Playing from",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lyrics",
|
||||
"Track number": "Track number",
|
||||
"Disk number": "Disk number",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Error logging in!",
|
||||
"Please try again later, or try another account.": "Please try again later, or try another account.",
|
||||
"Logout": "Logout",
|
||||
"Login using browser": "Login using browser",
|
||||
"Please login using your Deezer account:": "Please login using your Deezer account:",
|
||||
"...or paste your ARL/Token below:": "...or paste your ARL/Token below:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "By using this program, you disagree with Deezer's ToS.",
|
||||
"Only in Electron version!": "Only in Electron version!",
|
||||
"Search results for:": "Search results for:",
|
||||
"Error loading data!": "Error loading data!",
|
||||
"Try again later!": "Try again later!",
|
||||
"Search": "Search",
|
||||
"Streaming Quality": "Streaming Quality",
|
||||
"Download Quality": "Download Quality",
|
||||
"Downloads Directory": "Downloads Directory",
|
||||
"Simultaneous downloads": "Simultaneous downloads",
|
||||
"Always show download confirm dialog before downloading.": "Always show download confirm dialog before downloading.",
|
||||
"Show download dialog": "Show download dialog",
|
||||
"Create folders for artists": "Create folders for artists",
|
||||
"Create folders for albums": "Create folders for albums",
|
||||
"Download lyrics": "Download lyrics",
|
||||
"Variables": "Variables",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Show autocomplete in search",
|
||||
"Integrations": "Integrations",
|
||||
"This allows listening history, flow and recommendations to work properly.": "This allows listening history, flow and recommendations to work properly.",
|
||||
"Log track listens to Deezer": "Log track listens to Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Connect your LastFM account to allow scrobbling.",
|
||||
"Login with LastFM": "Login with LastFM",
|
||||
"Disconnect LastFM": "Disconnect LastFM",
|
||||
"Requires restart to apply!": "Requires restart to apply!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Enable Discord Rich Presence, requires restart to toggle!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Enable Discord join button for syncing tracks, requires restart to toggle!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Other",
|
||||
"Minimize to tray": "Minimize to tray",
|
||||
"Don't minimize to tray": "Don't minimize to tray",
|
||||
"Close on exit": "Close on exit",
|
||||
"Settings saved!": "Settings saved!",
|
||||
"Available only in Electron version!": "Available only in Electron version!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Select primary color",
|
||||
"Light theme": "Light theme",
|
||||
"Create folders for playlists": "Create folders for playlists",
|
||||
"About": "About",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram Releases",
|
||||
"Telegram Group": "Telegram Group",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android Group",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Agree",
|
||||
"Dismiss": "Dismiss",
|
||||
"Added to playlist!": "Added to playlist!",
|
||||
"Added to library!": "Added to library!",
|
||||
"Removed from library!": "Removed from library!",
|
||||
"Removed from playlist!": "Removed from playlist!",
|
||||
"Playlist deleted!": "Playlist deleted!",
|
||||
"Delete": "Delete",
|
||||
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?",
|
||||
"Force white tray icon": "Force white tray icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Force default (white) tray icon if theme incorrectly detected. Requires restart.",
|
||||
"Share": "Share",
|
||||
"Settings quality": "Settings quality",
|
||||
"Content language": "Content language",
|
||||
"Content country": "Content country",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/id.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Beranda",
|
||||
"Browse": "Telusuri",
|
||||
"Library": "Koleksi",
|
||||
"Tracks": "Lagu",
|
||||
"Playlists": "Daftar Putar",
|
||||
"Albums": "Album",
|
||||
"Artists": "Artis",
|
||||
"More": "Lebih banyak",
|
||||
"Settings": "Pengaturan",
|
||||
"Downloads": "Unduhan",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Cari atau tempel URL Deezer. Gunakan \"/\" untuk fokus dengan cepat.",
|
||||
"Play": "Putar",
|
||||
"Add to library": "Tambahkan ke koleksi",
|
||||
"Download": "Unduh",
|
||||
"fans": "penggemar",
|
||||
"tracks": "lagu",
|
||||
"Quality": "Kualitas",
|
||||
"Estimated size:": "Perkiraan ukuran:",
|
||||
"Start downloading": "Mulai mengunduh",
|
||||
"Cancel": "Batalkan",
|
||||
"Stream logging is disabled!": "Catatan pemutaran di nonaktifkan!",
|
||||
"Enable it in settings for history to work properly.": "Aktifkan di pengaturan agar riwayat berfungsi dengan benar.",
|
||||
"History": "Riwayat",
|
||||
"Create new playlist": "Buat daftar putar baru",
|
||||
"TRACKS": "LAGU",
|
||||
"Sort by": "Urut berdasarkan",
|
||||
"Date Added": "Tanggal Ditambahkan",
|
||||
"Name (A-Z)": "Nama (A-Z)",
|
||||
"Artist (A-Z)": "Artis (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Gagal memuat lirik atau lirik tidak tersedia!",
|
||||
"Create playlist": "Buat daftar putar",
|
||||
"Create": "Buat",
|
||||
"Add to playlist": "Tambahkan ke daftar putar",
|
||||
"Create new": "Buat baru",
|
||||
"Remove": "Hapus",
|
||||
"Play next": "Putar selanjutnya",
|
||||
"Add to queue": "Tambahkan ke antrean",
|
||||
"Remove from library": "Hapus dari koleksi",
|
||||
"Remove from playlist": "Hapus dari daftar putar",
|
||||
"Play track mix": "Putar lagu campuran",
|
||||
"Go to": "Pergi ke",
|
||||
"Track Mix": "Lagu Campuran",
|
||||
"Duration": "Durasi",
|
||||
"Released": "Dirilis",
|
||||
"Disk": "Disk",
|
||||
"albums": "album",
|
||||
"Play top": "Mainkan populer",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Tampilkan semua album",
|
||||
"Show all singles": "Tampilkan semua single",
|
||||
"Show more": "Tampilkan lebih banyak",
|
||||
"Downloaded": "Terunduh",
|
||||
"Queue": "Antrean",
|
||||
"Total": "Jumlah",
|
||||
"Stop": "Berhenti",
|
||||
"Start": "Mulai",
|
||||
"Show folder": "Tampilkan folder",
|
||||
"Clear queue": "Bersihkan antrean",
|
||||
"Playing from": "Memainkan dari",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lirik",
|
||||
"Track number": "Nomor lagu",
|
||||
"Disk number": "Nomor disk",
|
||||
"Explicit": "Eksplisit",
|
||||
"Source": "Sumber",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Gagal masuk!",
|
||||
"Please try again later, or try another account.": "Coba lagi nanti, atau coba akun lain.",
|
||||
"Logout": "Keluar",
|
||||
"Login using browser": "Masuk menggunakan browser",
|
||||
"Please login using your Deezer account:": "Silakan masuk menggunakan akun Deezer anda:",
|
||||
"...or paste your ARL/Token below:": "...atau tempelkan ARL/Token dibawah ini:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Masuk",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Dengan menggunakan program ini, kamu tidak setuju dengan ToS Deezer.",
|
||||
"Only in Electron version!": "Hanya dalam versi Electron!",
|
||||
"Search results for:": "Hasil pencarian untuk:",
|
||||
"Error loading data!": "Gagal memuat data!",
|
||||
"Try again later!": "Coba lagi nanti!",
|
||||
"Search": "Cari",
|
||||
"Streaming Quality": "Kualitas pemutaran",
|
||||
"Download Quality": "Kualitas unduhan",
|
||||
"Downloads Directory": "Folder Unduhan",
|
||||
"Simultaneous downloads": "Unduhan serentak",
|
||||
"Always show download confirm dialog before downloading.": "Selalu tampilkan dialog konfirmasi unduhan sebelum mengunduh.",
|
||||
"Show download dialog": "Tampilkan dialog unduhan",
|
||||
"Create folders for artists": "Buat folder untuk artis",
|
||||
"Create folders for albums": "Buat folder untuk album",
|
||||
"Download lyrics": "Unduh lirik",
|
||||
"Variables": "Variabel",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Tampilkan isi otomatis di pencarian",
|
||||
"Integrations": "Integrasi",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Hal ini memungkinkan riwayat mendengarkan, aliran, dan rekomendasi berfungsi dengan baik.",
|
||||
"Log track listens to Deezer": "Catat aktifitas mendengarkan lagu ke Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Hubungkan ke akun LastFM mu untuk mengijinkan scrobbling.",
|
||||
"Login with LastFM": "Masuk dengan LastFM",
|
||||
"Disconnect LastFM": "Putuskan LastFM",
|
||||
"Requires restart to apply!": "Mulai ulang untuk menerapkan!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Aktifkan Discord Rich Presence, perlu dimulai ulang untuk beralih!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Aktifkan tombol bergabung Discord untuk menyinkronkan lagu, perlu dimulai ulang untuk beralih!",
|
||||
"Discord Join Button": "Tombol Bergabung Discord",
|
||||
"Other": "Lainnya",
|
||||
"Minimize to tray": "Minimalkan ke Tray",
|
||||
"Don't minimize to tray": "Jangan minimalkan ke tray",
|
||||
"Close on exit": "Tutup saat keluar",
|
||||
"Settings saved!": "Pengaturan tersimpan!",
|
||||
"Available only in Electron version!": "Hanya tersedia di versi Electron!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Pilih warna utama",
|
||||
"Light theme": "Tema cerah",
|
||||
"Create folders for playlists": "Buat folder untuk daftar putar",
|
||||
"About": "Tentang",
|
||||
"Links:": "Tautan:",
|
||||
"Telegram Releases": "Telegram Rilis",
|
||||
"Telegram Group": "Telegram Grub",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Grub Android",
|
||||
"Credits:": "Kredit:",
|
||||
"Agree": "Setuju",
|
||||
"Dismiss": "Abaikan",
|
||||
"Added to playlist!": "Ditambahkan ke daftar putar!",
|
||||
"Added to library!": "Ditambahkan ke koleksi!",
|
||||
"Removed from library!": "Dihapus dari koleksi!",
|
||||
"Removed from playlist!": "Dihapus dari daftar putar!",
|
||||
"Playlist deleted!": "Daftar putar dihapus!",
|
||||
"Delete": "Hapus",
|
||||
"Are you sure you want to delete this playlist?": "Apakah kamu yakin ingin menghapus daftar putar ini?",
|
||||
"Force white tray icon": "Paksa ikon baki putih",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Paksa default (putih) ikon baki jika tema tidak terdeteksi dengan benar. Membutuhkan restart.",
|
||||
"Share": "Bagikan",
|
||||
"Settings quality": "Pengaturan kualitas",
|
||||
"Content language": "Bahasa konten",
|
||||
"Content country": "Wilayah konten",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/it.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Sfoglia",
|
||||
"Library": "Libreria",
|
||||
"Tracks": "Brani",
|
||||
"Playlists": "Playlist",
|
||||
"Albums": "Album",
|
||||
"Artists": "Artisti",
|
||||
"More": "Altro",
|
||||
"Settings": "Impostazioni",
|
||||
"Downloads": "Download",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Cerca qui o incolla un URL di Deezer. Usa \"/\" per mettere a fuoco questa barra.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Aggiungi alla libreria",
|
||||
"Download": "Scarica",
|
||||
"fans": "fan",
|
||||
"tracks": "brani",
|
||||
"Quality": "Qualità",
|
||||
"Estimated size:": "Dimensione stimata:",
|
||||
"Start downloading": "Inizia il download",
|
||||
"Cancel": "Annulla",
|
||||
"Stream logging is disabled!": "Il logging delle stream è disabilitato!",
|
||||
"Enable it in settings for history to work properly.": "Abilitalo nelle impostazioni per permettere alla cronologia di funzionare correttamente.",
|
||||
"History": "Cronologia",
|
||||
"Create new playlist": "Crea una playlist",
|
||||
"TRACKS": "BRANI",
|
||||
"Sort by": "Ordina per",
|
||||
"Date Added": "Data di aggiunta",
|
||||
"Name (A-Z)": "Nome (A-Z)",
|
||||
"Artist (A-Z)": "Artista (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Errore nel caricare i testi o testi non trovati!",
|
||||
"Create playlist": "Crea playlist",
|
||||
"Create": "Crea",
|
||||
"Add to playlist": "Aggiungi a playlist",
|
||||
"Create new": "Crea nuova",
|
||||
"Remove": "Rimuovi",
|
||||
"Play next": "Riproduci subito dopo",
|
||||
"Add to queue": "Aggiungi alla coda",
|
||||
"Remove from library": "Rimuovi dalla libreria",
|
||||
"Remove from playlist": "Rimuovi dalla playlist",
|
||||
"Play track mix": "Riproduci mix di brani",
|
||||
"Go to": "Vai a",
|
||||
"Track Mix": "Mix Di Tracce",
|
||||
"Duration": "Durata",
|
||||
"Released": "Data di uscita",
|
||||
"Disk": "Disco",
|
||||
"albums": "album",
|
||||
"Play top": "Riproduci dall'inizio",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Mostra tutti gli album",
|
||||
"Show all singles": "Mostra tutti i singoli",
|
||||
"Show more": "Mostra di più",
|
||||
"Downloaded": "Scaricato",
|
||||
"Queue": "Coda",
|
||||
"Total": "Totale",
|
||||
"Stop": "Stop",
|
||||
"Start": "Avvia",
|
||||
"Show folder": "Mostra cartella",
|
||||
"Clear queue": "Pulisci la coda",
|
||||
"Playing from": "Riproduzione da",
|
||||
"Info": "Informazioni",
|
||||
"Lyrics": "Testo",
|
||||
"Track number": "Numero della traccia",
|
||||
"Disk number": "Numero del disco",
|
||||
"Explicit": "Esplicito",
|
||||
"Source": "Fonte",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Errore durante il login!",
|
||||
"Please try again later, or try another account.": "Riprova più tardi, o prova un altro account.",
|
||||
"Logout": "Disconnettiti",
|
||||
"Login using browser": "Accedi utilizzando il browser",
|
||||
"Please login using your Deezer account:": "Effettua il login usando il tuo account Deezer:",
|
||||
"...or paste your ARL/Token below:": "...o incolla il tuo ARL/Token qui sotto:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Utilizzando questo programma, non sei d'accordo con il ToS di Deezer.",
|
||||
"Only in Electron version!": "Solo nella versione Electron!",
|
||||
"Search results for:": "Risultati della ricerca per:",
|
||||
"Error loading data!": "Errore nel caricamento dei dati!",
|
||||
"Try again later!": "Riprova più tardi!",
|
||||
"Search": "Cerca",
|
||||
"Streaming Quality": "Qualità Streaming",
|
||||
"Download Quality": "Qualità Download",
|
||||
"Downloads Directory": "Cartella Download",
|
||||
"Simultaneous downloads": "Download simultanei",
|
||||
"Always show download confirm dialog before downloading.": "Mostra sempre la conferma di download prima di scaricare.",
|
||||
"Show download dialog": "Mostra finestra di download",
|
||||
"Create folders for artists": "Crea cartelle per gli artisti",
|
||||
"Create folders for albums": "Crea cartelle per gli album",
|
||||
"Download lyrics": "Scarica testo",
|
||||
"Variables": "Variabili",
|
||||
"UI": "Interfaccia",
|
||||
"Show autocomplete in search": "Mostra elenco autocompletamento",
|
||||
"Integrations": "Integrazioni",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Questo permette di usare la cronologia, il Flow e le raccomandazioni per funzionare correttamente.",
|
||||
"Log track listens to Deezer": "Registra gli ascolti delle tracce a Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Collega il tuo account LastFM per consentire lo scrobbling.",
|
||||
"Login with LastFM": "Accedi con LastFM",
|
||||
"Disconnect LastFM": "Disconnetti LastFM",
|
||||
"Requires restart to apply!": "Richiede un riavvio!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Abilita Discord Rich Presence, richiede il riavvio!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Abilita il pulsante \"join\" di Discord per sincronizzare le tracce, richiede il riavvio!",
|
||||
"Discord Join Button": "Pulsante Unisciti di Discord",
|
||||
"Other": "Altro",
|
||||
"Minimize to tray": "Minimizza ad icona",
|
||||
"Don't minimize to tray": "Non minimizzare a icona",
|
||||
"Close on exit": "Chiudi all'uscita",
|
||||
"Settings saved!": "Impostazioni salvate!",
|
||||
"Available only in Electron version!": "Disponibile solo nella versione Electron!",
|
||||
"Crossfade (ms)": "Dissolvenza (ms)",
|
||||
"Select primary color": "Seleziona colore principale",
|
||||
"Light theme": "Tema chiaro",
|
||||
"Create folders for playlists": "Crea cartelle per le playlist",
|
||||
"About": "Informazioni",
|
||||
"Links:": "Link:",
|
||||
"Telegram Releases": "Rilasci su Telegram",
|
||||
"Telegram Group": "Gruppo Telegram",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Gruppo Telegram Android",
|
||||
"Credits:": "Crediti:",
|
||||
"Agree": "Accetta",
|
||||
"Dismiss": "Rifiuta",
|
||||
"Added to playlist!": "Aggiunto alla playlist!",
|
||||
"Added to library!": "Aggiunto alla libreria!",
|
||||
"Removed from library!": "Rimosso dalla libreria!",
|
||||
"Removed from playlist!": "Rimosso dalla playlist!",
|
||||
"Playlist deleted!": "Playlist eliminata!",
|
||||
"Delete": "Elimina",
|
||||
"Are you sure you want to delete this playlist?": "Sei sicuro di voler eliminare questa playlist?",
|
||||
"Force white tray icon": "Forza icona bianca nel vassoio",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Forza l'icona predefinita (bianca) nel vassoio se il tema è stato rilevato in modo errato. Richiede il riavvio.",
|
||||
"Share": "Condividi",
|
||||
"Settings quality": "Qualità delle Impostazioni",
|
||||
"Content language": "Lingua dei contenuti",
|
||||
"Content country": "Contenuto del Paese",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/ko.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Browse",
|
||||
"Library": "Library",
|
||||
"Tracks": "Tracks",
|
||||
"Playlists": "Playlists",
|
||||
"Albums": "Albums",
|
||||
"Artists": "Artists",
|
||||
"More": "More",
|
||||
"Settings": "Settings",
|
||||
"Downloads": "Downloads",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Search or paste Deezer URL. Use \"/\" to quickly focus.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Add to library",
|
||||
"Download": "Download",
|
||||
"fans": "fans",
|
||||
"tracks": "tracks",
|
||||
"Quality": "Quality",
|
||||
"Estimated size:": "Estimated size:",
|
||||
"Start downloading": "Start downloading",
|
||||
"Cancel": "Cancel",
|
||||
"Stream logging is disabled!": "Stream logging is disabled!",
|
||||
"Enable it in settings for history to work properly.": "Enable it in settings for history to work properly.",
|
||||
"History": "History",
|
||||
"Create new playlist": "Create new playlist",
|
||||
"TRACKS": "TRACKS",
|
||||
"Sort by": "Sort by",
|
||||
"Date Added": "Date Added",
|
||||
"Name (A-Z)": "Name (A-Z)",
|
||||
"Artist (A-Z)": "Artist (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Error loading lyrics or lyrics not found!",
|
||||
"Create playlist": "Create playlist",
|
||||
"Create": "Create",
|
||||
"Add to playlist": "Add to playlist",
|
||||
"Create new": "Create new",
|
||||
"Remove": "Remove",
|
||||
"Play next": "Play next",
|
||||
"Add to queue": "Add to queue",
|
||||
"Remove from library": "Remove from library",
|
||||
"Remove from playlist": "Remove from playlist",
|
||||
"Play track mix": "Play track mix",
|
||||
"Go to": "Go to",
|
||||
"Track Mix": "Track Mix",
|
||||
"Duration": "Duration",
|
||||
"Released": "Released",
|
||||
"Disk": "Disk",
|
||||
"albums": "albums",
|
||||
"Play top": "Play top",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Show all albums",
|
||||
"Show all singles": "Show all singles",
|
||||
"Show more": "Show more",
|
||||
"Downloaded": "Downloaded",
|
||||
"Queue": "Queue",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Show folder": "Show folder",
|
||||
"Clear queue": "Clear queue",
|
||||
"Playing from": "Playing from",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Lyrics",
|
||||
"Track number": "Track number",
|
||||
"Disk number": "Disk number",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Source",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Error logging in!",
|
||||
"Please try again later, or try another account.": "Please try again later, or try another account.",
|
||||
"Logout": "Logout",
|
||||
"Login using browser": "Login using browser",
|
||||
"Please login using your Deezer account:": "Please login using your Deezer account:",
|
||||
"...or paste your ARL/Token below:": "...or paste your ARL/Token below:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "By using this program, you disagree with Deezer's ToS.",
|
||||
"Only in Electron version!": "Only in Electron version!",
|
||||
"Search results for:": "Search results for:",
|
||||
"Error loading data!": "Error loading data!",
|
||||
"Try again later!": "Try again later!",
|
||||
"Search": "Search",
|
||||
"Streaming Quality": "Streaming Quality",
|
||||
"Download Quality": "Download Quality",
|
||||
"Downloads Directory": "Downloads Directory",
|
||||
"Simultaneous downloads": "Simultaneous downloads",
|
||||
"Always show download confirm dialog before downloading.": "Always show download confirm dialog before downloading.",
|
||||
"Show download dialog": "Show download dialog",
|
||||
"Create folders for artists": "Create folders for artists",
|
||||
"Create folders for albums": "Create folders for albums",
|
||||
"Download lyrics": "Download lyrics",
|
||||
"Variables": "Variables",
|
||||
"UI": "UI",
|
||||
"Show autocomplete in search": "Show autocomplete in search",
|
||||
"Integrations": "Integrations",
|
||||
"This allows listening history, flow and recommendations to work properly.": "This allows listening history, flow and recommendations to work properly.",
|
||||
"Log track listens to Deezer": "Log track listens to Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Connect your LastFM account to allow scrobbling.",
|
||||
"Login with LastFM": "Login with LastFM",
|
||||
"Disconnect LastFM": "Disconnect LastFM",
|
||||
"Requires restart to apply!": "Requires restart to apply!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Enable Discord Rich Presence, requires restart to toggle!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Enable Discord join button for syncing tracks, requires restart to toggle!",
|
||||
"Discord Join Button": "Discord Join Button",
|
||||
"Other": "Other",
|
||||
"Minimize to tray": "Minimize to tray",
|
||||
"Don't minimize to tray": "Don't minimize to tray",
|
||||
"Close on exit": "Close on exit",
|
||||
"Settings saved!": "Settings saved!",
|
||||
"Available only in Electron version!": "Available only in Electron version!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Select primary color",
|
||||
"Light theme": "Light theme",
|
||||
"Create folders for playlists": "Create folders for playlists",
|
||||
"About": "About",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Telegram Releases",
|
||||
"Telegram Group": "Telegram Group",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Telegram Android Group",
|
||||
"Credits:": "Credits:",
|
||||
"Agree": "Agree",
|
||||
"Dismiss": "Dismiss",
|
||||
"Added to playlist!": "Added to playlist!",
|
||||
"Added to library!": "Added to library!",
|
||||
"Removed from library!": "Removed from library!",
|
||||
"Removed from playlist!": "Removed from playlist!",
|
||||
"Playlist deleted!": "Playlist deleted!",
|
||||
"Delete": "Delete",
|
||||
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?",
|
||||
"Force white tray icon": "Force white tray icon",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Force default (white) tray icon if theme incorrectly detected. Requires restart.",
|
||||
"Share": "Share",
|
||||
"Settings quality": "Settings quality",
|
||||
"Content language": "Content language",
|
||||
"Content country": "Content country",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/pl.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Strona główna",
|
||||
"Browse": "Przeglądaj",
|
||||
"Library": "Biblioteka",
|
||||
"Tracks": "Utwory",
|
||||
"Playlists": "Playlisty",
|
||||
"Albums": "Albumy",
|
||||
"Artists": "Wykonawcy",
|
||||
"More": "Więcej",
|
||||
"Settings": "Ustawienia",
|
||||
"Downloads": "Pobrane",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Wyszukaj lub wklej adres URL Deezera. Wciśnij \"/\" aby szybko uaktywnić pasek wyszukiwania.",
|
||||
"Play": "Odtwórz",
|
||||
"Add to library": "Dodaj do biblioteki",
|
||||
"Download": "Pobierz",
|
||||
"fans": "fani",
|
||||
"tracks": "utwory",
|
||||
"Quality": "Jakość",
|
||||
"Estimated size:": "Szacowany rozmiar:",
|
||||
"Start downloading": "Rozpocznij pobieranie",
|
||||
"Cancel": "Anuluj",
|
||||
"Stream logging is disabled!": "Rejestrowanie strumieniowania jest wyłączone!",
|
||||
"Enable it in settings for history to work properly.": "Włącz to w ustawieniach, aby historia działała prawidłowo.",
|
||||
"History": "Historia",
|
||||
"Create new playlist": "Utwórz nową playlistę",
|
||||
"TRACKS": "UTWORY",
|
||||
"Sort by": "Sortuj wg",
|
||||
"Date Added": "Data dodania",
|
||||
"Name (A-Z)": "Nazwa (A-Z)",
|
||||
"Artist (A-Z)": "Artysta (A-Z)",
|
||||
"Album (A-Z)": "Album (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Wystąpił błąd podczas ładowania tekstu lub tekst nie został znaleziony!",
|
||||
"Create playlist": "Utwórz playlistę",
|
||||
"Create": "Utwórz",
|
||||
"Add to playlist": "Dodaj do playlisty",
|
||||
"Create new": "Utwórz nową",
|
||||
"Remove": "Usuń",
|
||||
"Play next": "Odtwarzaj następne",
|
||||
"Add to queue": "Dodaj do kolejki",
|
||||
"Remove from library": "Usuń z biblioteki",
|
||||
"Remove from playlist": "Usuń z playlisty",
|
||||
"Play track mix": "Odtwarzaj losowo",
|
||||
"Go to": "Przejdź do",
|
||||
"Track Mix": "Mieszaj utwory",
|
||||
"Duration": "Czas trwania",
|
||||
"Released": "Wydano",
|
||||
"Disk": "Płyta",
|
||||
"albums": "albumy",
|
||||
"Play top": "Odtwarzaj topkę",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Pokaż wszystkie albumy",
|
||||
"Show all singles": "Pokaż wszystkie single",
|
||||
"Show more": "Pokaż więcej",
|
||||
"Downloaded": "Pobrane",
|
||||
"Queue": "Kolejka",
|
||||
"Total": "Łącznie",
|
||||
"Stop": "Zatrzymaj",
|
||||
"Start": "Rozpocznij",
|
||||
"Show folder": "Pokaż folder",
|
||||
"Clear queue": "Wyczyść kolejkę",
|
||||
"Playing from": "Odtwarzanie z",
|
||||
"Info": "Info",
|
||||
"Lyrics": "Tekst",
|
||||
"Track number": "Numer utworu",
|
||||
"Disk number": "Numer płyty",
|
||||
"Explicit": "Wulgarne",
|
||||
"Source": "Źródło",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Błąd podczas logowania!",
|
||||
"Please try again later, or try another account.": "Spróbuj ponownie później lub spróbuj innego konta.",
|
||||
"Logout": "Wyloguj",
|
||||
"Login using browser": "Zaloguj się za pomocą przeglądarki",
|
||||
"Please login using your Deezer account:": "Zaloguj się używając swojego konta Deezer:",
|
||||
"...or paste your ARL/Token below:": "...lub wklej ARL/Token poniżej:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Zaloguj",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Korzystając z tego programu, nie zgadzasz się z ToS Deezera.",
|
||||
"Only in Electron version!": "Tylko w wersji Electron!",
|
||||
"Search results for:": "Wyniki wyszukiwania dla:",
|
||||
"Error loading data!": "Błąd ładowania danych!",
|
||||
"Try again later!": "Spróbuj ponownie później!",
|
||||
"Search": "Szukaj",
|
||||
"Streaming Quality": "Jakość odtwarzania",
|
||||
"Download Quality": "Jakość pobierania",
|
||||
"Downloads Directory": "Katalog pobierania",
|
||||
"Simultaneous downloads": "Jednoczesne pobieranie",
|
||||
"Always show download confirm dialog before downloading.": "Zawsze proś o potwierdzenie przed pobieraniem.",
|
||||
"Show download dialog": "Pokazuj okno dialogowe pobierania",
|
||||
"Create folders for artists": "Twórz foldery wykonawców",
|
||||
"Create folders for albums": "Twórz foldery albumów",
|
||||
"Download lyrics": "Pobierz tekst",
|
||||
"Variables": "Zmienne",
|
||||
"UI": "Interfejs",
|
||||
"Show autocomplete in search": "Pokaż autouzupełnianie w wyszukiwarce",
|
||||
"Integrations": "Połącz",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Pozwala na działanie historii odtwarzania, rekomendacji i automatycznych playlist.",
|
||||
"Log track listens to Deezer": "Zapisuj historię odtwarzania na koncie Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Połącz swoje konto LastFM, aby umożliwić scrobbling.",
|
||||
"Login with LastFM": "Zaloguj używając LastFM",
|
||||
"Disconnect LastFM": "Odłącz LastFM",
|
||||
"Requires restart to apply!": "Zmiany wymagają ponownego uruchomienia!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Włącz Szczegółowy Widok Discord, wymaga ponownego uruchomienia!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Włącz w Discordzie przycisk dołączenia, aby synchronizować utwory, wymaga ponownego uruchomienia!",
|
||||
"Discord Join Button": "Pokaż przycisk dołączenia do Discord",
|
||||
"Other": "Inne",
|
||||
"Minimize to tray": "Minimalizuj do zasobnika",
|
||||
"Don't minimize to tray": "Nie minimalizuj do zasobnika",
|
||||
"Close on exit": "Wyłącz po zamknięciu okna",
|
||||
"Settings saved!": "Ustawienia zapisane!",
|
||||
"Available only in Electron version!": "Dostępne tylko w wersji Electron!",
|
||||
"Crossfade (ms)": "Przejście (ms)",
|
||||
"Select primary color": "Wybierz podstawowy kolor",
|
||||
"Light theme": "Wybierz jasny motyw",
|
||||
"Create folders for playlists": "Utwórz folder dla playlist",
|
||||
"About": "O programie",
|
||||
"Links:": "Adresy:",
|
||||
"Telegram Releases": "Nowe wydania w Telegram",
|
||||
"Telegram Group": "Grupa w Telegramie",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Grupa Telegram dla wydań na Android",
|
||||
"Credits:": "Twórcy:",
|
||||
"Agree": "Akceptuję",
|
||||
"Dismiss": "Odrzuć",
|
||||
"Added to playlist!": "Dodano do playlisty!",
|
||||
"Added to library!": "Dodano do biblioteki!",
|
||||
"Removed from library!": "Usunięto z biblioteki!",
|
||||
"Removed from playlist!": "Usunięto z playlisty!",
|
||||
"Playlist deleted!": "Playlista została usunięta!",
|
||||
"Delete": "Usuń",
|
||||
"Are you sure you want to delete this playlist?": "Na pewno chcesz usunąć tę playlistę?",
|
||||
"Force white tray icon": "Wymuś białą ikonę w zasobniku",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Wymuś domyślną (białą) ikonę w zasobniku paska zadań jeśli motyw został nieprawidłowo odczytany. Wymaga ponownego uruchomienia.",
|
||||
"Share": "Udostępnij",
|
||||
"Settings quality": "Jakość z ustawień",
|
||||
"Content language": "Język treści",
|
||||
"Content country": "Kraj treści",
|
||||
"Website": "Strona internetowa",
|
||||
"Visit website": "Odwiedź stronę internetową",
|
||||
"New update available:": "Dostępna jest nowa aktualizacja:"
|
||||
}
|
141
buildfiles/app/client/src/locales/pt.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Início",
|
||||
"Browse": "Navegar",
|
||||
"Library": "Biblioteca",
|
||||
"Tracks": "Faixas",
|
||||
"Playlists": "Playlists",
|
||||
"Albums": "Álbuns",
|
||||
"Artists": "Artistas",
|
||||
"More": "Mais",
|
||||
"Settings": "Configurações",
|
||||
"Downloads": "Downloads",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Pesquise ou cole a URL do Deezer. Use \"/\" para focar rapidamente.",
|
||||
"Play": "Reproduzir",
|
||||
"Add to library": "Adicionar à biblioteca",
|
||||
"Download": "Download",
|
||||
"fans": "fans",
|
||||
"tracks": "faixas",
|
||||
"Quality": "Qualidade",
|
||||
"Estimated size:": "Tempo estimado:",
|
||||
"Start downloading": "Iniciar download",
|
||||
"Cancel": "Cancelar",
|
||||
"Stream logging is disabled!": "O registro de depuração extra está desativado!",
|
||||
"Enable it in settings for history to work properly.": "Habilite nas configurações para que o histórico funcione corretamente.",
|
||||
"History": "Histórico",
|
||||
"Create new playlist": "Criar nova playlist",
|
||||
"TRACKS": "FAIXAS",
|
||||
"Sort by": "Ordenar por",
|
||||
"Date Added": "Data de adição",
|
||||
"Name (A-Z)": "Nome (A-Z)",
|
||||
"Artist (A-Z)": "Artista (A-Z)",
|
||||
"Album (A-Z)": "Álbum (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Erro ao carregar letra ou letra não encontrada!",
|
||||
"Create playlist": "Criar playlist",
|
||||
"Create": "Criar",
|
||||
"Add to playlist": "Adicionar à playlist",
|
||||
"Create new": "Criar nova",
|
||||
"Remove": "Remover",
|
||||
"Play next": "Reproduzir à seguir",
|
||||
"Add to queue": "Adicionar à fila",
|
||||
"Remove from library": "Remover da biblioteca",
|
||||
"Remove from playlist": "Remover da playlist",
|
||||
"Play track mix": "Reproduzir mistura de trilha",
|
||||
"Go to": "Ir para",
|
||||
"Track Mix": "Faixa Mix",
|
||||
"Duration": "Duração",
|
||||
"Released": "Lançamento",
|
||||
"Disk": "Disco",
|
||||
"albums": "álbuns",
|
||||
"Play top": "Reproduzir no topo",
|
||||
"Radio": "Rádio",
|
||||
"Show all albums": "Mostrar todos os álbuns",
|
||||
"Show all singles": "Mostrar todos os singles",
|
||||
"Show more": "Mostrar mais",
|
||||
"Downloaded": "Baixados",
|
||||
"Queue": "Fila de Reprodução",
|
||||
"Total": "Total",
|
||||
"Stop": "Parar",
|
||||
"Start": "Começar",
|
||||
"Show folder": "Mostrar pasta",
|
||||
"Clear queue": "Limpar fila",
|
||||
"Playing from": "Reproduzindo de",
|
||||
"Info": "Informações",
|
||||
"Lyrics": "Letra",
|
||||
"Track number": "Número de faixa",
|
||||
"Disk number": "Numero de disco",
|
||||
"Explicit": "Explícito",
|
||||
"Source": "Fonte",
|
||||
"ID": "Identificação",
|
||||
"Error logging in!": "Erro de login!",
|
||||
"Please try again later, or try another account.": "Por favor, tente novamente mais tarde ou tente outra conta.",
|
||||
"Logout": "Desconectar",
|
||||
"Login using browser": "Login usando o navegador",
|
||||
"Please login using your Deezer account:": "Faça login usando sua conta do Deezer:",
|
||||
"...or paste your ARL/Token below:": "...ou cole seu ARL/Token abaixo:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Ao usar este programa, você discorda dos termos e condições de uso do Deezer.",
|
||||
"Only in Electron version!": "Apenas na versão do Electron!",
|
||||
"Search results for:": "Resultado de pesquisa para:",
|
||||
"Error loading data!": "Erro ao carregar dados!",
|
||||
"Try again later!": "Tente novamente mais tarde!",
|
||||
"Search": "Pesquisa",
|
||||
"Streaming Quality": "Qualidade do streaming",
|
||||
"Download Quality": "Qualiadade do download",
|
||||
"Downloads Directory": "Pasta de Download",
|
||||
"Simultaneous downloads": "Downloads simultâneos",
|
||||
"Always show download confirm dialog before downloading.": "Sempre mostrar diálogo de confirmação de download antes de baixar.",
|
||||
"Show download dialog": "Mostrar diálogo de download",
|
||||
"Create folders for artists": "Criar pastas para artistas",
|
||||
"Create folders for albums": "Criar pastas para álbuns",
|
||||
"Download lyrics": "Baixar letra",
|
||||
"Variables": "Variáveis",
|
||||
"UI": "IU",
|
||||
"Show autocomplete in search": "Mostrar autocompletar na pesquisa",
|
||||
"Integrations": "Integrações",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Isto permite que o histórico de ouvidas, flow e recomendações funcionem corretamente.",
|
||||
"Log track listens to Deezer": "Log de faixas ouvidas para o Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Conecte sua conta do LastFM para permitir o scrobbling.",
|
||||
"Login with LastFM": "Login com LastFM",
|
||||
"Disconnect LastFM": "Desconectar LastFM",
|
||||
"Requires restart to apply!": "Requer reinicialização do aplicativo para aplicar!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Ativar o Rich Presence do Discord, requer reiniciar para alternar!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Ativar o botão de adesão do Discord para sincronizar faixas requer reinicialização para alternar!",
|
||||
"Discord Join Button": "Botão de Entrada Discord",
|
||||
"Other": "Outro",
|
||||
"Minimize to tray": "Minimizar para a bandeja",
|
||||
"Don't minimize to tray": "Não minimizar para a bandeja",
|
||||
"Close on exit": "Fechar ao sair",
|
||||
"Settings saved!": "Configurações salvas!",
|
||||
"Available only in Electron version!": "Disponível apenas na versão completa!",
|
||||
"Crossfade (ms)": "Transição suave (ms)",
|
||||
"Select primary color": "Escolha a cor primária",
|
||||
"Light theme": "Tema Claro",
|
||||
"Create folders for playlists": "Criar pastas para playlists",
|
||||
"About": "Sobre",
|
||||
"Links:": "Links:",
|
||||
"Telegram Releases": "Versões no Telegram",
|
||||
"Telegram Group": "Grupo do Telegram",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Grupo do Android no Telegram",
|
||||
"Credits:": "Créditos:",
|
||||
"Agree": "Concordo",
|
||||
"Dismiss": "Dispensar",
|
||||
"Added to playlist!": "Adicionar à playlist!",
|
||||
"Added to library!": "Adicionado à biblioteca!",
|
||||
"Removed from library!": "Removido da biblioteca!",
|
||||
"Removed from playlist!": "Removido da playlist!",
|
||||
"Playlist deleted!": "Playlist deletada!",
|
||||
"Delete": "Deletar",
|
||||
"Are you sure you want to delete this playlist?": "Você tem certeza que deseja excluir esta playlist?",
|
||||
"Force white tray icon": "Forçar ícone de bandeja branco",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Forçar ícone de bandeja (branco) padrão se o tema for detectado incorretamente. Requer reinicialização.",
|
||||
"Share": "Compartilhar",
|
||||
"Settings quality": "Configurações de qualidade",
|
||||
"Content language": "Linguagem do conteúdo",
|
||||
"Content country": "País do conteúdo",
|
||||
"Website": "Site",
|
||||
"Visit website": "Visite o site",
|
||||
"New update available:": "Nova atualização disponível:"
|
||||
}
|
141
buildfiles/app/client/src/locales/ro.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"Browse": "Caută",
|
||||
"Library": "Librărie",
|
||||
"Tracks": "Piese",
|
||||
"Playlists": "Playlist-uri",
|
||||
"Albums": "Albume",
|
||||
"Artists": "Artiști",
|
||||
"More": "Mai mult",
|
||||
"Settings": "Setări",
|
||||
"Downloads": "Descărcări",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Caută sau lipește URL-ul Deezer. Folosește \"/\" pentru a se focaliza rapid.",
|
||||
"Play": "Play",
|
||||
"Add to library": "Adaugă la librărie",
|
||||
"Download": "Descărcați",
|
||||
"fans": "fani",
|
||||
"tracks": "piese",
|
||||
"Quality": "Calitate",
|
||||
"Estimated size:": "Dimensiune estimată:",
|
||||
"Start downloading": "Începe descărcarea",
|
||||
"Cancel": "Anulează",
|
||||
"Stream logging is disabled!": "Stream logging-ul este dezactivat!",
|
||||
"Enable it in settings for history to work properly.": "Activați-l în setări pentru ca istoricul să funcționeze corect.",
|
||||
"History": "Istoric",
|
||||
"Create new playlist": "Crează un nou playlist",
|
||||
"TRACKS": "PIESE",
|
||||
"Sort by": "Sortează după",
|
||||
"Date Added": "Dată Adăugare",
|
||||
"Name (A-Z)": "Nume (A-Z)",
|
||||
"Artist (A-Z)": "Artiști (A-Z)",
|
||||
"Album (A-Z)": "Albume (A-Z)",
|
||||
"Error loading lyrics or lyrics not found!": "Eroare la încărcarea versurilor sau versurile nu au fost găsite!",
|
||||
"Create playlist": "Crează un playlist",
|
||||
"Create": "Creează",
|
||||
"Add to playlist": "Adaugă la un playlist",
|
||||
"Create new": "Crează nou",
|
||||
"Remove": "Șterge",
|
||||
"Play next": "Redă următorul",
|
||||
"Add to queue": "Adaugă la coadă",
|
||||
"Remove from library": "Șterge din librărie",
|
||||
"Remove from playlist": "Șterge din playlist",
|
||||
"Play track mix": "Redă mix-ul piesei",
|
||||
"Go to": "Accesați",
|
||||
"Track Mix": "Mix-ul Piesei",
|
||||
"Duration": "Durată",
|
||||
"Released": "Lansat",
|
||||
"Disk": "Disc",
|
||||
"albums": "albume",
|
||||
"Play top": "Redă de la început",
|
||||
"Radio": "Radio",
|
||||
"Show all albums": "Afișează toate albumele",
|
||||
"Show all singles": "Arată toate melodiile",
|
||||
"Show more": "Arată mai multe",
|
||||
"Downloaded": "Descărcate",
|
||||
"Queue": "Coadă",
|
||||
"Total": "Total",
|
||||
"Stop": "Stop",
|
||||
"Start": "Începe",
|
||||
"Show folder": "Arată folder-ul",
|
||||
"Clear queue": "Șterge coada",
|
||||
"Playing from": "Redare din",
|
||||
"Info": "Informații",
|
||||
"Lyrics": "Versuri",
|
||||
"Track number": "Numărul piesei",
|
||||
"Disk number": "Numărul discului",
|
||||
"Explicit": "Explicit",
|
||||
"Source": "Sursă",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Eroare la autentificare!",
|
||||
"Please try again later, or try another account.": "Te rugăm să încerci din nou mai târziu, sau încearcă cu un alt cont.",
|
||||
"Logout": "Deconectează-te",
|
||||
"Login using browser": "Autentificare utilizând browserul",
|
||||
"Please login using your Deezer account:": "Te rugăm să te conectezi utilizând contul tau Deezer:",
|
||||
"...or paste your ARL/Token below:": "...sau lipiți ARL/Token-ul mai jos:",
|
||||
"ARL/Token": "ARL/Token",
|
||||
"Login": "Login",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Folosind acest program, nu sunteți de acord cu ToS-ul Deezer.",
|
||||
"Only in Electron version!": "Doar în versiunea Electron!",
|
||||
"Search results for:": "Rezultatele căutării pentru:",
|
||||
"Error loading data!": "Eroare la încărcarea datelor!",
|
||||
"Try again later!": "Încearcă din nou mai târziu!",
|
||||
"Search": "Caută",
|
||||
"Streaming Quality": "Calitatea streaming-ului",
|
||||
"Download Quality": "Calitatea descărcărilor",
|
||||
"Downloads Directory": "Descărcați in",
|
||||
"Simultaneous downloads": "Descărcări simultane",
|
||||
"Always show download confirm dialog before downloading.": "Arată întotdeauna confirmarea a descărcării înainte de descărcare.",
|
||||
"Show download dialog": "Arată pagina de download",
|
||||
"Create folders for artists": "Crează foldere pentru artiști",
|
||||
"Create folders for albums": "Crează foldere pentru albume",
|
||||
"Download lyrics": "Descărcați versurile .LRC",
|
||||
"Variables": "Variabile",
|
||||
"UI": "Interfață",
|
||||
"Show autocomplete in search": "Afișează lista de autocompletare",
|
||||
"Integrations": "Integrări",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Aceasta permite folosirea istoricului, Flow-ului și recomandările pentru a funcționa corect.",
|
||||
"Log track listens to Deezer": "Înregistrează ascultările la Deezer",
|
||||
"Connect your LastFM account to allow scrobbling.": "Conectați-vă contul LastFM pentru a permite scrobbling-ul.",
|
||||
"Login with LastFM": "Conectează-te cu LastFM",
|
||||
"Disconnect LastFM": "Deconectează LastFM",
|
||||
"Requires restart to apply!": "Necesită repornirea pentru a aplica!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Activează Discord Rich Presence, necesită repornirea pentru a comuta!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Activează butonul de join la Discord pentru sincronizarea pieselor, necesită repornire în comutator!",
|
||||
"Discord Join Button": "Butonul de join Discord",
|
||||
"Other": "Altele",
|
||||
"Minimize to tray": "Minimizează în bara de programe",
|
||||
"Don't minimize to tray": "Nu minimiza în bara de programe",
|
||||
"Close on exit": "Închide la ieșire",
|
||||
"Settings saved!": "Setările au fost salvate!",
|
||||
"Available only in Electron version!": "Disponibil doar în versiunea Electron!",
|
||||
"Crossfade (ms)": "Crossfade (ms)",
|
||||
"Select primary color": "Selectaţi culoarea primară",
|
||||
"Light theme": "Temă luminoasă",
|
||||
"Create folders for playlists": "Creați foldere pentru playlist-uri",
|
||||
"About": "Despre",
|
||||
"Links:": "Link-uri:",
|
||||
"Telegram Releases": "Lansări Telegram",
|
||||
"Telegram Group": "Grup Telegram",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Group Android Telegram",
|
||||
"Credits:": "Contribuţii:",
|
||||
"Agree": "Permite",
|
||||
"Dismiss": "Respingeți",
|
||||
"Added to playlist!": "Adăugat la playlist!",
|
||||
"Added to library!": "Adăugat la bibliotecă!",
|
||||
"Removed from library!": "Eliminat din bibliotecă!",
|
||||
"Removed from playlist!": "Eliminat din playlist!",
|
||||
"Playlist deleted!": "Playlist detectat!",
|
||||
"Delete": "Ștergeți",
|
||||
"Are you sure you want to delete this playlist?": "Ești sigur că dorești să ștergi acest playlist?",
|
||||
"Force white tray icon": "Forțează icon alb",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Forțează icon implici (alb) dacă tema este detectată incorect. Necesită repornire a aplicației.",
|
||||
"Share": "Distribuiți",
|
||||
"Settings quality": "Setări Calitate",
|
||||
"Content language": "Limbajul conținutului",
|
||||
"Content country": "Țara conținutului",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|
141
buildfiles/app/client/src/locales/ru.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Home": "Главная",
|
||||
"Browse": "Обзор",
|
||||
"Library": "Избранное",
|
||||
"Tracks": "Треки",
|
||||
"Playlists": "Плейлисты",
|
||||
"Albums": "Альбомы",
|
||||
"Artists": "Артисты",
|
||||
"More": "Ещё",
|
||||
"Settings": "Настройки",
|
||||
"Downloads": "Загрузки",
|
||||
"Search or paste Deezer URL. Use / to quickly focus.": "Введите запрос или ссылку. \"/\" для быстрого поиска.",
|
||||
"Play": "Воспроизвести",
|
||||
"Add to library": "Добавить в Избранное",
|
||||
"Download": "Скачать",
|
||||
"fans": "поклонники",
|
||||
"tracks": "треки",
|
||||
"Quality": "Качество звука",
|
||||
"Estimated size:": "Приблизительный размер:",
|
||||
"Start downloading": "Начать загрузку",
|
||||
"Cancel": "Отмена",
|
||||
"Stream logging is disabled!": "Отправка статистики отключена!",
|
||||
"Enable it in settings for history to work properly.": "Включите её в настройках для работы рекомендаций.",
|
||||
"History": "История",
|
||||
"Create new playlist": "Новый плейлист",
|
||||
"TRACKS": "Треки",
|
||||
"Sort by": "Сортировать по",
|
||||
"Date Added": "Дата добавления",
|
||||
"Name (A-Z)": "Название (А - Я)",
|
||||
"Artist (A-Z)": "Исполнитель (А - Я)",
|
||||
"Album (A-Z)": "Альбом (A - Я)",
|
||||
"Error loading lyrics or lyrics not found!": "Ошибка получения текста!",
|
||||
"Create playlist": "Создать плейлист",
|
||||
"Create": "Создать",
|
||||
"Add to playlist": "Добавить в плейлист",
|
||||
"Create new": "Создать новый",
|
||||
"Remove": "Удалить",
|
||||
"Play next": "Играть следующим",
|
||||
"Add to queue": "Добавить в очередь",
|
||||
"Remove from library": "Удалить из Избранного",
|
||||
"Remove from playlist": "Удалить из плейлиста",
|
||||
"Play track mix": "Воспроизвести микс",
|
||||
"Go to": "Перейти к",
|
||||
"Track Mix": "Микс",
|
||||
"Duration": "Продолжительность",
|
||||
"Released": "Релиз",
|
||||
"Disk": "Диск",
|
||||
"albums": "альбомы",
|
||||
"Play top": "Играть популярные",
|
||||
"Radio": "Радио",
|
||||
"Show all albums": "Показать все",
|
||||
"Show all singles": "Показать все синглы",
|
||||
"Show more": "Ещё",
|
||||
"Downloaded": "Загрузки",
|
||||
"Queue": "Очередь",
|
||||
"Total": "Всего",
|
||||
"Stop": "Остановить",
|
||||
"Start": "Пуск",
|
||||
"Show folder": "Открыть папку",
|
||||
"Clear queue": "Очистить очередь",
|
||||
"Playing from": "Сейчас играет",
|
||||
"Info": "Инфо",
|
||||
"Lyrics": "Текст песни",
|
||||
"Track number": "Дорожка",
|
||||
"Disk number": "Номер диска",
|
||||
"Explicit": "18+",
|
||||
"Source": "Источник",
|
||||
"ID": "ID",
|
||||
"Error logging in!": "Ошибка авторизации!",
|
||||
"Please try again later, or try another account.": "Пожалуйста, повторите попытку позже или попробуйте другой аккаунт.",
|
||||
"Logout": "Выход",
|
||||
"Login using browser": "Войти через браузер",
|
||||
"Please login using your Deezer account:": "Войдите, используя свой аккаунт Deezer:",
|
||||
"...or paste your ARL/Token below:": "...или вставьте ваш токен (ARL) ниже:",
|
||||
"ARL/Token": "Токен (ARL) ",
|
||||
"Login": "Вход",
|
||||
"By using this program, you disagree with Deezer's ToS.": "Используя эту программу, вы не соглашаетесь с правилами использования Deezer.",
|
||||
"Only in Electron version!": "Только в версии Electron!",
|
||||
"Search results for:": "Результаты поиска для:",
|
||||
"Error loading data!": "Ошибка при загрузке данных!",
|
||||
"Try again later!": "Повторите попытку позже!",
|
||||
"Search": "Поиск",
|
||||
"Streaming Quality": "Качество при воспроизведении",
|
||||
"Download Quality": "Качество при загрузке",
|
||||
"Downloads Directory": "Папка загрузок",
|
||||
"Simultaneous downloads": "Количество одновременных загрузок",
|
||||
"Always show download confirm dialog before downloading.": "Подтверждать загрузки.",
|
||||
"Show download dialog": "Подтверждение",
|
||||
"Create folders for artists": "Создавать папки для исполнителей",
|
||||
"Create folders for albums": "Создавать папки для альбомов",
|
||||
"Download lyrics": "Скачивать тексты",
|
||||
"Variables": "Переменные",
|
||||
"UI": "Интерфейс",
|
||||
"Show autocomplete in search": "Подсказки при поиске",
|
||||
"Integrations": "Интеграции",
|
||||
"This allows listening history, flow and recommendations to work properly.": "Для правильной работы Flow, рекомендаций и истории.",
|
||||
"Log track listens to Deezer": "Отправлять статистику",
|
||||
"Connect your LastFM account to allow scrobbling.": "Подключите ваш аккаунт LastFM, чтобы разрешить скробблинг.",
|
||||
"Login with LastFM": "Авторизоваться через LastFM",
|
||||
"Disconnect LastFM": "Отключить LastFM",
|
||||
"Requires restart to apply!": "Требуется перезапуск приложения!",
|
||||
"Enable Discord Rich Presence, requires restart to toggle!": "Включить Discord Rich Presence, требуется перезапуск!",
|
||||
"Discord Rich Presence": "Discord Rich Presence",
|
||||
"Enable Discord join button for syncing tracks, requires restart to toggle!": "Включить кнопку вступления Discord для синхронизации треков, требуется перезапуск!",
|
||||
"Discord Join Button": "Кнопка \"Вступить\" в Discord",
|
||||
"Other": "Другое",
|
||||
"Minimize to tray": "Сворачивать в трей",
|
||||
"Don't minimize to tray": "Не сворачивать в трей",
|
||||
"Close on exit": "Закрывать при выходе",
|
||||
"Settings saved!": "Настройки сохранены!",
|
||||
"Available only in Electron version!": "Доступно только в версии на Electron!",
|
||||
"Crossfade (ms)": "Кроссфейд (мс)",
|
||||
"Select primary color": "Выберите основной цвет",
|
||||
"Light theme": "Светлая тема",
|
||||
"Create folders for playlists": "Создавать папки для плейлистов",
|
||||
"About": "О приложении",
|
||||
"Links:": "Ссылки:",
|
||||
"Telegram Releases": "Релизы в Telegram",
|
||||
"Telegram Group": "Группа в Telegram",
|
||||
"Discord": "Discord",
|
||||
"Telegram Android Group": "Обсуждение Freezer Android",
|
||||
"Credits:": "Благодарность:",
|
||||
"Agree": "Согласен",
|
||||
"Dismiss": "Отмена",
|
||||
"Added to playlist!": "Добавлено в плейлист!",
|
||||
"Added to library!": "Добавлено в избранное!",
|
||||
"Removed from library!": "Удалено из Избранного!",
|
||||
"Removed from playlist!": "Удалено из плейлиста!",
|
||||
"Playlist deleted!": "Плейлист удален!",
|
||||
"Delete": "Удалить",
|
||||
"Are you sure you want to delete this playlist?": "Вы точно хотите удалить этот плейлист?",
|
||||
"Force white tray icon": "Белый значок в трее",
|
||||
"Force default (white) tray icon if theme incorrectly detected. Requires restart.": "Принудительно использовать белый значок, если тема определена неправильно. Требуется перезапуск.",
|
||||
"Share": "Поделиться",
|
||||
"Settings quality": "Качество настроек",
|
||||
"Content language": "Язык контента",
|
||||
"Content country": "Страна контента",
|
||||
"Website": "Website",
|
||||
"Visit website": "Visit website",
|
||||
"New update available:": "New update available:"
|
||||
}
|