- {title}
- {#if subtitle}
- {subtitle}
- {/if}
-
- {artist.name}
+
+ {title}
+ {#if subtitle}
+ {subtitle}
+ {/if}
+
+ {artist.name}
{#if !hideDownload || $butShowThisDownloadLinkInstead}
{#if $butShowThisDownloadLinkInstead}
@@ -131,6 +132,7 @@
height: 96px;
}
.album-image-wrapper {
+ flex: 0 0 auto;
transition: 0.1s border ease-out;
}
.album-metadata {
@@ -139,6 +141,9 @@
flex: 1 1 0px;
align-items: flex-start;
gap: 0.5em;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
}
.album-download {
cursor: pointer;
@@ -159,6 +164,9 @@
.metadata {
flex: 1 1 0px;
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
}
.progress-state {
diff --git a/app/src/lib/Track.svelte b/app/src/lib/Track.svelte
index 41a8eea..52c114f 100644
--- a/app/src/lib/Track.svelte
+++ b/app/src/lib/Track.svelte
@@ -51,7 +51,6 @@
.track-left {
flex: 1 1 0px;
- white-space: normal;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
diff --git a/app/src/lib/dev.js b/app/src/lib/dev.js
index e2adfac..8de6b70 100644
--- a/app/src/lib/dev.js
+++ b/app/src/lib/dev.js
@@ -1 +1 @@
-export const dev = true;
\ No newline at end of file
+export const dev = false;
\ No newline at end of file
diff --git a/app/src/lib/download.js b/app/src/lib/download.js
index d1b5195..f34069d 100644
--- a/app/src/lib/download.js
+++ b/app/src/lib/download.js
@@ -1,6 +1,11 @@
import { get, writable } from 'svelte/store';
-import { queue } from './stores';
+import { queue, saveOnDownload } from './stores';
import { dev } from './dev';
+import { toast } from '@zerodevx/svelte-toast'
+import { saveAs } from 'file-saver';
+
+const successTheme = {'--toastBarBackground': 'rgb(131, 243, 131)'};
+const failureTheme = {'--toastBarBackground': 'rgb(243, 131, 131)'};
function getWebsocketLocation() {
if (dev) return 'ws://localhost:4500/';
@@ -24,13 +29,15 @@ export function startDownload(id, metadata, isAlbum) {
downloadLink
};
+ toast.push(`Started download for
${metadata.artist.name} - ${metadata.title}`);
+
queue.set([...get(queue), queueItem]);
let type = isAlbum ? 'album' : 'track'
const ws = new WebSocket(`${getWebsocketLocation()}api/${type}?id=${id}`);
ws.onmessage = (m) => {
const d = JSON.parse(m.data);
- console.log(d);
+ //console.log(d);
if (d.key === 'downloadInfo') {
logLocal.push(`[${d.data.data.title}] ${d.data.state}`);
log.set(logLocal);
@@ -42,10 +49,15 @@ export function startDownload(id, metadata, isAlbum) {
success.set(true);
progress.set(100);
downloadLink.set(d.data);
+ toast.push(`Downloaded
${metadata.artist.name} - ${metadata.title}!`, {theme: successTheme});
+ if (get(saveOnDownload)) {
+ saveAs(d.data, d.data.split('/').pop());
+ }
} else if (d.key === 'finishDownload') {
setTimeout(() => {
if (!get(success)) {
success.set(false);
+ toast.push(`Downloading
${metadata.artist.name} - ${metadata.title} failed!`, {theme: failureTheme});
logLocal.push('Server didn\'t send a download link back!');
logLocal.push('This may be due to errors during the download or temporary connection issues');
logLocal.push('Try again, and if it still doesn\'t work, annoy oat until it does again');
@@ -67,6 +79,7 @@ export function startDownload(id, metadata, isAlbum) {
logLocal.push(`${e}`);
log.set(logLocal);
success.set(false);
+ toast.push(`Downloading
${metadata.artist.name} - ${metadata.title} failed!`, {theme: failureTheme});
}
ws.onclose = (e) => {
if (e.code !== 1000) {
@@ -74,6 +87,7 @@ export function startDownload(id, metadata, isAlbum) {
logLocal.push(`websocket closed unexpectedly with code ${e.code}`, `${e.reason}`);
log.set(logLocal);
success.set(false);
+ toast.push(`Downloading
${metadata.artist.name} - ${metadata.title} failed!`, {theme: failureTheme});
}
}
}
\ No newline at end of file
diff --git a/app/src/lib/stores.js b/app/src/lib/stores.js
index 8a2f125..02e26b9 100644
--- a/app/src/lib/stores.js
+++ b/app/src/lib/stores.js
@@ -1,3 +1,4 @@
import { writable } from "svelte/store";
-export let queue = writable([]);
\ No newline at end of file
+export let queue = writable([]);
+export let saveOnDownload = writable(false);
\ No newline at end of file
diff --git a/package.json b/package.json
index a17d514..cc50d03 100644
--- a/package.json
+++ b/package.json
@@ -24,11 +24,13 @@
"license": "AGPL-3.0",
"dependencies": {
"@fortawesome/free-solid-svg-icons": "^6.1.2",
+ "@zerodevx/svelte-toast": "^0.7.2",
"deemix": "git+https://gitlab.com/RemixDev/deemix-js",
"deezer-js": "^1.3.5",
"dotenv": "^10.0.0",
"express": "^4.17.3",
"express-ws": "^5.0.2",
+ "file-saver": "^2.0.5",
"sirv-cli": "^2.0.2",
"svelte-fontawesome": "^0.0.3",
"svelte-inview": "^3.0.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7c123fb..34d09c5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7,12 +7,14 @@ specifiers:
'@types/express': ^4.17.13
'@types/express-ws': ^3.0.1
'@types/ws': ^8.2.3
+ '@zerodevx/svelte-toast': ^0.7.2
bufferutil: ^4.0.6
deemix: git+https://gitlab.com/RemixDev/deemix-js
deezer-js: ^1.3.5
dotenv: ^10.0.0
express: ^4.17.3
express-ws: ^5.0.2
+ file-saver: ^2.0.5
rollup: ^2.68.0
rollup-plugin-css-only: ^3.1.0
rollup-plugin-livereload: ^2.0.5
@@ -31,11 +33,13 @@ specifiers:
dependencies:
'@fortawesome/free-solid-svg-icons': 6.1.2
+ '@zerodevx/svelte-toast': 0.7.2
deemix: gitlab.com/RemixDev/deemix-js/a105b03beb93cc2efa5d723d7f2e3cb2237d4f08
deezer-js: 1.3.5
dotenv: 10.0.0
express: 4.17.3
express-ws: 5.0.2_te4mbskzuxzlkfrbqjipouglzi
+ file-saver: 2.0.5
sirv-cli: 2.0.2
svelte-fontawesome: 0.0.3
svelte-inview: 3.0.1_svelte@3.46.4
@@ -284,6 +288,10 @@ packages:
'@types/node': 17.0.21
dev: true
+ /@zerodevx/svelte-toast/0.7.2:
+ resolution: {integrity: sha512-vWiY6IqsstcOoQ8PFBuFuxgPkj1JFAGhUF9gC7wLx7c5A9SSfdtxWs/39ekGSIeyJK0yqWhTcmzGrCEWSELzDw==}
+ dev: false
+
/accepts/1.3.8:
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
engines: {node: '>= 0.6'}
@@ -714,6 +722,10 @@ packages:
resolution: {integrity: sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==}
dev: false
+ /file-saver/2.0.5:
+ resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==}
+ dev: false
+
/fill-range/7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
@@ -1060,7 +1072,7 @@ packages:
dev: false
/methods/1.1.2:
- resolution: {integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=}
+ resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
engines: {node: '>= 0.6'}
dev: false
@@ -1695,7 +1707,7 @@ packages:
node-gyp-build: 4.3.0
/util-deprecate/1.0.2:
- resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: false
/utils-merge/1.0.1: