asdf
|
@ -0,0 +1 @@
|
|||
/public/build/
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 3.1 KiB |
|
@ -0,0 +1,124 @@
|
|||
html, body {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgb(0,100,200);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: rgb(0,80,160);
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input, button, select, textarea {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
-webkit-padding: 0.4em 0;
|
||||
padding: 0.4em;
|
||||
margin: 0 0 0.5em 0;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
input:disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
button {
|
||||
color: #333;
|
||||
background-color: #f4f4f4;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
button:not(:disabled):active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
border-color: #666;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
* {
|
||||
transition: 0.1s background-color ease-out;
|
||||
}
|
||||
|
||||
.link {
|
||||
cursor: pointer;
|
||||
transition: 0.1s color ease-out, 0.1s filter ease-out;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: medium;
|
||||
}
|
||||
.big {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#albums {
|
||||
margin-top: 20px;
|
||||
width: 600px;
|
||||
max-width: 98%;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #0a0a0f;
|
||||
color: #fff;
|
||||
accent-color: rgb(131, 131, 243);
|
||||
}
|
||||
.small {
|
||||
color: #c8c8d2;
|
||||
}
|
||||
.link {
|
||||
color:#ea74ac;
|
||||
}
|
||||
.link:hover {
|
||||
color: #f484b6;
|
||||
filter: drop-shadow( 0px 0px 2px #f484b6);
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
body {
|
||||
background-color: #f0f0f0;
|
||||
color: #1e1e2d;
|
||||
accent-color: #ea74ac;
|
||||
}
|
||||
.small {
|
||||
color: #888;
|
||||
}
|
||||
.link {
|
||||
color:rgb(131, 131, 243);
|
||||
}
|
||||
.link:hover {
|
||||
color: rgb(151, 151, 255);
|
||||
filter: drop-shadow( 0px 0px 2px #8383F3);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
||||
|
||||
<title>Svelte app</title>
|
||||
|
||||
<link rel='icon' type='image/png' href='/favicon.png'>
|
||||
<link rel='stylesheet' href='/global.css'>
|
||||
<link rel='stylesheet' href='/build/bundle.css'>
|
||||
|
||||
<script defer src='/build/bundle.js'></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,166 @@
|
|||
<style>
|
||||
.album {
|
||||
padding: 15px;
|
||||
margin: 2px;
|
||||
font-size: large;
|
||||
border-radius: 10px 10px 0px 0px;
|
||||
transition: 0.1s border-left ease-out, 0.1s background-color ease-in-out;
|
||||
min-height: 96px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.album-image {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
border-radius: 10px;
|
||||
transition: 0.1s border ease-out, 0.1s box-shadow ease-out;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
}
|
||||
.album-image-wrapper {
|
||||
transition: 0.1s border ease-out;
|
||||
}
|
||||
.album-metadata {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
.metadata {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.album-download {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
transition: 0.1s filter ease-out;
|
||||
}
|
||||
|
||||
.album-bottom {
|
||||
padding: 0px;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
border-radius: 0px 0px 10px 10px;
|
||||
transition: 0.1s border-left ease-out;
|
||||
}
|
||||
|
||||
.album-download {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.album {
|
||||
background-color: #161627;
|
||||
box-shadow: 0px 0px 12px #000;
|
||||
border-left: 0rem solid rgb(131, 131, 243);
|
||||
}
|
||||
.album:hover {
|
||||
border-left: 0.25rem solid rgb(131, 131, 243);
|
||||
background-color: #181829;
|
||||
}
|
||||
.album-image {
|
||||
border: 0px solid rgb(131, 131, 243);
|
||||
box-shadow: 0px 0px 15px #000;
|
||||
}
|
||||
.album:hover .album-image {
|
||||
border: 2px solid rgb(131, 131, 243);
|
||||
box-shadow: 0px 0px 30px #000;
|
||||
}
|
||||
.album-image-wrapper {
|
||||
border: 2px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
.album:hover .album-image-wrapper {
|
||||
border: 0px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
.album-download {
|
||||
filter: invert(100%);
|
||||
}
|
||||
.album-download:hover {
|
||||
filter: invert(50%) sepia(58%) saturate(893%) hue-rotate(206deg) brightness(99%) contrast(92%) drop-shadow( 0px 0px 5px #8383F3);
|
||||
}
|
||||
.album-bottom {
|
||||
background-color: #112;
|
||||
border-left: 0rem solid rgb(131, 131, 243);
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
.album {
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.2);
|
||||
border-left: 0rem solid #ea74ac;
|
||||
}
|
||||
.album:hover {
|
||||
border-left: 0.25rem solid #ea74ac;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.album-image {
|
||||
border: 0px solid #ea74ac;
|
||||
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.album:hover .album-image {
|
||||
border: 2px solid #ea74ac;
|
||||
box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.album-image-wrapper {
|
||||
border: 2px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
.album:hover .album-image-wrapper {
|
||||
border: 0px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
.album-download {
|
||||
filter: none;
|
||||
}
|
||||
.album-download:hover {
|
||||
filter: invert(65%) sepia(45%) saturate(772%) hue-rotate(295deg) brightness(103%) contrast(91%) drop-shadow( 0px 0px 5px #f484b6);
|
||||
}
|
||||
.album-bottom {
|
||||
background-color: #ffffff;
|
||||
border-left: 0rem solid #ea74ac;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import {onMount} from 'svelte/internal';
|
||||
import Track from './Track.svelte';
|
||||
import {queryTracks} from './api';
|
||||
import {downloadAlbum} from './download';
|
||||
import Loading from './Loading.svelte';
|
||||
|
||||
export let id;
|
||||
export let title;
|
||||
export let cover;
|
||||
export let artist;
|
||||
|
||||
let tracks = [];
|
||||
|
||||
onMount(async () => {
|
||||
let album = await queryTracks(id);
|
||||
tracks = album.tracks;
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="album" id="album-{id}">
|
||||
<div class="album-metadata">
|
||||
<span class="metadata">
|
||||
<span class="big">{title}</span>
|
||||
<br>
|
||||
<span class="small">by {artist}</span>
|
||||
</span>
|
||||
<img class="album-download" width="48" height="48" src="assets/download.svg" alt="Download" on:click={() => downloadAlbum(id)}>
|
||||
</div>
|
||||
<div class="album-image-wrapper">
|
||||
<img class="album-image" width="128" height="128" src="https://e-cdns-images.dzcdn.net/images/cover/{cover}/128x128-000000-80-0-0.jpg" alt="Cover">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="album-bottom" id="album-bottom-{id}">
|
||||
{#if tracks.length === 0}
|
||||
<Loading/>
|
||||
{:else}
|
||||
{#each tracks as track}
|
||||
<Track id={track.id} title={track.title} artist={track.artist} duration={track.duration}/>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
|
@ -0,0 +1,32 @@
|
|||
<script>
|
||||
import Search from './Search.svelte';
|
||||
import Album from './Album.svelte';
|
||||
import Download from './Download.svelte';
|
||||
|
||||
import {albums, display, displays, downloading} from './stores';
|
||||
</script>
|
||||
|
||||
<style>
|
||||
content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
|
||||
<main>
|
||||
<content>
|
||||
{#if $display === displays.AlbumSearch}
|
||||
<Search/>
|
||||
<div id="albums">
|
||||
{#each $albums as album}
|
||||
<Album id={album.id} title={album.title} cover={album.cover} artist={album.artist.name}/><br>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if $display === displays.Download && $downloading}
|
||||
<Download id={$downloading.id} isAlbum={$downloading.isAlbum}/>
|
||||
{/if}
|
||||
</content>
|
||||
</main>
|
|
@ -0,0 +1,45 @@
|
|||
<script>
|
||||
import { onMount } from 'svelte/internal';
|
||||
import { writable } from 'svelte/store';
|
||||
import Loading from './Loading.svelte';
|
||||
import { startWebsocket } from './websocket'
|
||||
|
||||
export let id;
|
||||
export let isAlbum;
|
||||
|
||||
let title;
|
||||
let artist;
|
||||
let coverArt;
|
||||
let log = writable([]);
|
||||
let progress = writable(0);
|
||||
|
||||
onMount(async () => {
|
||||
startWebsocket(id, isAlbum, s => {log.update(l => {return [...l, s].slice(-5)})}, c => {coverArt = c}, t => {title = t}, a => {artist = a}, p => {progress.set(p)});
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if title && artist && coverArt}
|
||||
<div class="album album-downloading" id="album-{id}">
|
||||
<div class="album-metadata">
|
||||
<span class="metadata">
|
||||
<span class="big">{title}</span>
|
||||
<br>
|
||||
<span class="small">by {artist}</span>
|
||||
</span>
|
||||
<div id="progress-state">
|
||||
{#each $log as l}
|
||||
<br>{l}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<div class="album-image-wrapper">
|
||||
<img class="album-image" width="128" height="128" src="{coverArt}" alt="Cover">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if $progress > 0}
|
||||
<div id="progress-bar"><div id="progress-bar-inner" style="height:100%;width:{$progress}%"></div></div>
|
||||
{/if}
|
||||
{:else}
|
||||
<Loading/>
|
||||
{/if}
|
|
@ -0,0 +1,51 @@
|
|||
<style>
|
||||
.lds-ring {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.lds-ring div {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin: 8px;
|
||||
border-radius: 50%;
|
||||
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
}
|
||||
.lds-ring div:nth-child(1) {
|
||||
animation-delay: -0.45s;
|
||||
}
|
||||
.lds-ring div:nth-child(2) {
|
||||
animation-delay: -0.3s;
|
||||
}
|
||||
.lds-ring div:nth-child(3) {
|
||||
animation-delay: -0.15s;
|
||||
}
|
||||
@keyframes lds-ring {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.lds-ring div {
|
||||
border: 8px solid #fff;
|
||||
border-color: #fff transparent transparent transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.lds-ring div {
|
||||
border: 8px solid #1e1e2d;
|
||||
border-color: #1e1e2d transparent transparent transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="lds-ring"><div></div><div></div><div></div><div></div></div>
|
|
@ -0,0 +1,55 @@
|
|||
<script>
|
||||
import {clearAlbums, pushAlbum} from './stores';
|
||||
import {querySearch} from './api';
|
||||
|
||||
let searchbar;
|
||||
|
||||
async function search() {
|
||||
const value = searchbar.value;
|
||||
clearAlbums();
|
||||
if (value !== '') {
|
||||
let albums = await querySearch(value);
|
||||
albums.forEach(pushAlbum);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
input {
|
||||
background-color: #112;
|
||||
color: #fff;
|
||||
box-shadow: 0px 0px 15px #000;
|
||||
border-bottom: 0rem solid rgb(131, 131, 243);
|
||||
}
|
||||
input:focus, input:hover {
|
||||
border-bottom: 0.25rem solid rgb(131, 131, 243);
|
||||
background-color: #161626;
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
input {
|
||||
background-color: #ffffff;
|
||||
color: #1e1e2d;
|
||||
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.2);
|
||||
border-bottom: 0rem solid #ea74ac;
|
||||
}
|
||||
input:focus, input:hover {
|
||||
border-bottom: 0.25rem solid #ea74ac;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
margin: 5px;
|
||||
width: 550px;
|
||||
max-width: 98%;
|
||||
padding: 15px;
|
||||
font-size: x-large;
|
||||
border: none;
|
||||
border-radius: 7px;
|
||||
transition: 0.1s border-bottom ease-out, 0.1s background-color ease-in-out;
|
||||
}
|
||||
</style>
|
||||
|
||||
<input type="search" id="album-search" name="q" bind:this={searchbar} on:change={search}>
|
|
@ -0,0 +1,98 @@
|
|||
<style>
|
||||
.track .album-download {
|
||||
position: relative;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
.track {
|
||||
padding: 10px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
margin: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: large;
|
||||
transition: 0.05s background-color ease-out, 0.1s border-left ease-out;
|
||||
}
|
||||
.track:nth-last-child(1) {
|
||||
border-bottom: none;
|
||||
border-radius: 0px 0px 15px 15px;
|
||||
}
|
||||
|
||||
.track .album-download {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.track-download-wrapper {
|
||||
position: relative;
|
||||
bottom: 20px;
|
||||
height: 50%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.album-download {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
transition: 0.1s filter ease-out;
|
||||
position: relative;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.track {
|
||||
border-bottom: 3px solid #0a0a0f;
|
||||
border-left: 0rem solid rgb(131, 131, 243);
|
||||
}
|
||||
.track:hover {
|
||||
background-color: #161627;
|
||||
border-left: 0.25rem solid rgb(131, 131, 243);
|
||||
}
|
||||
.album-download {
|
||||
filter: invert(100%);
|
||||
}
|
||||
.album-download:hover {
|
||||
filter: invert(50%) sepia(58%) saturate(893%) hue-rotate(206deg) brightness(99%) contrast(92%) drop-shadow( 0px 0px 5px #8383F3);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.track {
|
||||
border-bottom: 3px solid #f0f0f0;
|
||||
border-left: 0rem solid #ea74ac;
|
||||
}
|
||||
.track:hover {
|
||||
background-color: #fafafa;
|
||||
border-left: 0.25rem solid #ea74ac;
|
||||
}
|
||||
.album-download {
|
||||
filter: none;
|
||||
}
|
||||
.album-download:hover {
|
||||
filter: invert(65%) sepia(45%) saturate(772%) hue-rotate(295deg) brightness(103%) contrast(91%) drop-shadow( 0px 0px 5px #f484b6);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import {downloadTrack} from './download';
|
||||
|
||||
export let id;
|
||||
export let title;
|
||||
export let artist;
|
||||
export let duration;
|
||||
|
||||
function formatTime(s) {
|
||||
return Math.floor(s / 60).toString().padStart(2, '0') + ':' + (s % 60).toString().padStart(2, '0');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="track" id="track-{id}">
|
||||
<span>{artist} - {title}</span>
|
||||
<span>
|
||||
<span class="track-download-wrapper" on:click={downloadTrack}>
|
||||
<img class="album-download" width="32" height="32" src="assets/download.svg" alt="Download">
|
||||
</span>
|
||||
{formatTime(duration)}
|
||||
</span>
|
||||
</div>
|
|
@ -0,0 +1,9 @@
|
|||
export async function querySearch(q) {
|
||||
let response = await fetch(`http://localhost:4500/api/search?search=${encodeURI(q)}`);
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
export async function queryTracks(id) {
|
||||
let response = await fetch(`http://localhost:4500/api/album?id=${id}`);
|
||||
return await response.json();
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import {downloading, display, displays} from './stores';
|
||||
|
||||
export function downloadAlbum(id) {
|
||||
display.set(displays.Download);
|
||||
downloading.set({id: id, isAlbum: true});
|
||||
}
|
||||
export function downloadTrack(id) {
|
||||
display.set(displays.Download);
|
||||
downloading.set({id: id, isAlbum: false});
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import App from './App.svelte';
|
||||
|
||||
const app = new App({
|
||||
target: document.body,
|
||||
props: {
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
|
@ -0,0 +1,19 @@
|
|||
import {writable} from 'svelte/store';
|
||||
|
||||
export const albums = writable([]);
|
||||
|
||||
export function clearAlbums() {
|
||||
albums.set([]);
|
||||
}
|
||||
export function pushAlbum(id) {
|
||||
albums.update((l) => [...l, id]);
|
||||
}
|
||||
|
||||
export const displays = {
|
||||
AlbumSearch: 0,
|
||||
Download: 1,
|
||||
}
|
||||
|
||||
export let display = writable(displays.AlbumSearch);
|
||||
|
||||
export let downloading = writable(null);
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
function getWebsocketLocation() {
|
||||
return window.window.location.toString().replace('https://', 'wss://').replace('http://', 'ws://');
|
||||
}
|
||||
*/
|
||||
function getWebsocketLocation() {
|
||||
return 'ws://localhost:4500/';
|
||||
}
|
||||
|
||||
export function startWebsocket(id, isAlbum, log, coverArt, title, artist, progress) {
|
||||
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);
|
||||
if (d.key === 'downloadInfo') {
|
||||
log(`[${d.data.data.title}] ${d.data.state}`);
|
||||
} else if (d.key === 'updateQueue') {
|
||||
progress(d.data.progress);
|
||||
} else if (d.key === 'coverArt') {
|
||||
log('Fetched cover art');
|
||||
coverArt(d.data);
|
||||
} else if (d.key === 'metadata') {
|
||||
log('Fetched metadata');
|
||||
title(d.data.title);
|
||||
artist(d.data.artist);
|
||||
} else if (d.key === 'download') {
|
||||
console.log(d.data);
|
||||
download(d.data);
|
||||
} else if (d.key === 'finishDownload') {
|
||||
log('Download finished');
|
||||
} else if (d.key === 'zipping') {
|
||||
log('Zipping up files');
|
||||
}
|
||||
};
|
||||
}
|
33
package.json
|
@ -6,7 +6,10 @@
|
|||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"quickrun": "tsc && node dist/index.js",
|
||||
"build": "tsc"
|
||||
"build": "tsc",
|
||||
"febuild": "rollup -c",
|
||||
"fedev": "rollup -c -w",
|
||||
"start": "sirv app/public --no-clear"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -14,29 +17,39 @@
|
|||
},
|
||||
"keywords": [
|
||||
"deemix",
|
||||
"piracy"
|
||||
"piracy",
|
||||
"svelte"
|
||||
],
|
||||
"author": "oatmealine",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"deemix": "git+https://git.freezerapp.xyz/RemixDev/deemix-js",
|
||||
"deezer-js": "^1.2.4",
|
||||
"deezer-js": "^1.3.5",
|
||||
"dotenv": "^10.0.0",
|
||||
"express": "^4.17.1",
|
||||
"express": "^4.17.3",
|
||||
"express-ws": "^5.0.2",
|
||||
"sirv-cli": "^2.0.2",
|
||||
"timeago.js": "^4.0.2",
|
||||
"toml": "^3.0.0",
|
||||
"winston": "^3.3.3",
|
||||
"ws": "^8.2.3"
|
||||
"winston": "^3.6.0",
|
||||
"ws": "^8.5.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"bufferutil": "^4.0.5",
|
||||
"utf-8-validate": "^5.0.7"
|
||||
"bufferutil": "^4.0.6",
|
||||
"utf-8-validate": "^5.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^4.4.4",
|
||||
"@rollup/plugin-commonjs": "^17.1.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/express-ws": "^3.0.1",
|
||||
"@types/ws": "^8.2.0"
|
||||
"@types/ws": "^8.2.3",
|
||||
"rollup": "^2.68.0",
|
||||
"rollup-plugin-css-only": "^3.1.0",
|
||||
"rollup-plugin-livereload": "^2.0.5",
|
||||
"rollup-plugin-svelte": "^7.1.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"svelte": "^3.46.4",
|
||||
"typescript": "^4.5.5"
|
||||
}
|
||||
}
|
||||
|
|
1034
pnpm-lock.yaml
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
@ -0,0 +1,163 @@
|
|||
@media (prefers-color-scheme: dark) {
|
||||
.lds-ring div {
|
||||
border: 8px solid #fff;
|
||||
border-color: #fff transparent transparent transparent;
|
||||
}
|
||||
#progress-bar {
|
||||
background-color: #161627;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
background-color: rgb(131, 131, 243);
|
||||
}
|
||||
.slider {
|
||||
background-color: rgb(131, 131, 243);
|
||||
}
|
||||
.slider:hover {
|
||||
filter: drop-shadow( 0px 0px 5px #8383F3);
|
||||
}
|
||||
#progress-state {
|
||||
background-color: #0a0a0f;
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
#progress-bar {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
background-color: #ea74ac;
|
||||
}
|
||||
.slider {
|
||||
background-color: #ea74ac;
|
||||
}
|
||||
.slider:hover {
|
||||
filter: drop-shadow( 0px 0px 5px #ea74ac);
|
||||
}
|
||||
#git {
|
||||
filter: invert(100%);
|
||||
}
|
||||
#progress-state {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
}
|
||||
|
||||
#progress {
|
||||
width: 600px;
|
||||
max-width: 98%;
|
||||
}
|
||||
|
||||
#progress-bar {
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
|
||||
#header {
|
||||
display: flex;
|
||||
align-items: left;
|
||||
justify-content: left;
|
||||
flex-direction: row;
|
||||
}
|
||||
#header > * {
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
#header .link {
|
||||
font-size: x-large;
|
||||
text-decoration: none;
|
||||
}
|
||||
#header img {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
/* The switch - the box around the slider */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-transition: .2s;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
-webkit-transition: .2s;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(26px);
|
||||
-ms-transform: translateX(26px);
|
||||
transform: translateX(26px);
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
.slider.round {
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#header-left {
|
||||
width: 100%;
|
||||
}
|
||||
#header-left > * {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
#progress-state {
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
border-radius: 10px;
|
||||
width: 80%;
|
||||
padding: 6px;
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
.album-downloading {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: rgb(255, 155, 155, 0.3);
|
||||
padding: 20px;
|
||||
border-radius: 15px;
|
||||
border: 3px solid rgb(255, 155, 155, 0.8);
|
||||
text-align: center;
|
||||
margin: 15px;
|
||||
width: 400px;
|
||||
display: none; /* this is changed by the js */
|
||||
}
|
||||
.error .big {
|
||||
font-size: x-large;
|
||||
}
|
450
public/index.css
|
@ -1,450 +0,0 @@
|
|||
@media (prefers-color-scheme: dark) {
|
||||
* {
|
||||
transition: 0.1s background-color ease-out;
|
||||
}
|
||||
body {
|
||||
background-color: #0a0a0f;
|
||||
color: #fff;
|
||||
accent-color: rgb(131, 131, 243);
|
||||
}
|
||||
input {
|
||||
background-color: #112;
|
||||
color: #fff;
|
||||
box-shadow: 0px 0px 15px #000;
|
||||
border-bottom: 0rem solid rgb(131, 131, 243);
|
||||
}
|
||||
input:focus, input:hover {
|
||||
border-bottom: 0.25rem solid rgb(131, 131, 243);
|
||||
background-color: #161626;
|
||||
}
|
||||
.album {
|
||||
background-color: #161627;
|
||||
box-shadow: 0px 0px 12px #000;
|
||||
border-left: 0rem solid rgb(131, 131, 243);
|
||||
}
|
||||
.album:hover {
|
||||
border-left: 0.25rem solid rgb(131, 131, 243);
|
||||
background-color: #181829;
|
||||
}
|
||||
.small {
|
||||
color: #888;
|
||||
}
|
||||
.album-image {
|
||||
border: 0px solid rgb(131, 131, 243);
|
||||
box-shadow: 0px 0px 15px #000;
|
||||
}
|
||||
.album:hover .album-image {
|
||||
border: 2px solid rgb(131, 131, 243);
|
||||
box-shadow: 0px 0px 30px #000;
|
||||
}
|
||||
.album-image-wrapper {
|
||||
border: 2px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
.album:hover .album-image-wrapper {
|
||||
border: 0px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
.link {
|
||||
color:rgb(131, 131, 243);
|
||||
}
|
||||
.link:hover {
|
||||
color: rgb(151, 151, 255);
|
||||
filter: drop-shadow( 0px 0px 2px #8383F3);
|
||||
}
|
||||
.album-download {
|
||||
filter: invert(100%);
|
||||
}
|
||||
.album-download:hover {
|
||||
filter: invert(50%) sepia(58%) saturate(893%) hue-rotate(206deg) brightness(99%) contrast(92%) drop-shadow( 0px 0px 5px #8383F3);
|
||||
}
|
||||
.lds-ring div {
|
||||
border: 8px solid #fff;
|
||||
border-color: #fff transparent transparent transparent;
|
||||
}
|
||||
#progress-bar {
|
||||
background-color: #161627;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
background-color: rgb(131, 131, 243);
|
||||
}
|
||||
.album-bottom {
|
||||
background-color: #112;
|
||||
border-left: 0rem solid rgb(131, 131, 243);
|
||||
}
|
||||
.album:hover .album-bottom {
|
||||
border-left: 0.25rem solid rgb(131, 131, 243);
|
||||
}
|
||||
.track {
|
||||
border-bottom: 3px solid #0a0a0f;
|
||||
border-left: 0rem solid rgb(131, 131, 243);
|
||||
}
|
||||
.track:hover {
|
||||
background-color: #161627;
|
||||
border-left: 0.25rem solid rgb(131, 131, 243);
|
||||
}
|
||||
.slider {
|
||||
background-color: rgb(131, 131, 243);
|
||||
}
|
||||
.slider:hover {
|
||||
filter: drop-shadow( 0px 0px 5px #8383F3);
|
||||
}
|
||||
#progress-state {
|
||||
background-color: #0a0a0f;
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
body {
|
||||
background-color: #f0f0f0;
|
||||
color: #1e1e2d;
|
||||
accent-color: #ea74ac;
|
||||
}
|
||||
input {
|
||||
background-color: #ffffff;
|
||||
color: #1e1e2d;
|
||||
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.2);
|
||||
border-bottom: 0rem solid #ea74ac;
|
||||
}
|
||||
input:focus, input:hover {
|
||||
border-bottom: 0.25rem solid #ea74ac;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.album {
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.2);
|
||||
border-left: 0rem solid #ea74ac;
|
||||
}
|
||||
.album:hover {
|
||||
border-left: 0.25rem solid #ea74ac;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.small {
|
||||
color: #c8c8d2;
|
||||
}
|
||||
.album-image {
|
||||
border: 0px solid #ea74ac;
|
||||
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.album:hover .album-image {
|
||||
border: 2px solid #ea74ac;
|
||||
box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.album-image-wrapper {
|
||||
border: 2px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
.album:hover .album-image-wrapper {
|
||||
border: 0px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
.link {
|
||||
color:#ea74ac;
|
||||
}
|
||||
.link:hover {
|
||||
color: #f484b6;
|
||||
filter: drop-shadow( 0px 0px 2px #f484b6);
|
||||
}
|
||||
.album-download {
|
||||
filter: none;
|
||||
}
|
||||
.album-download:hover {
|
||||
filter: invert(65%) sepia(45%) saturate(772%) hue-rotate(295deg) brightness(103%) contrast(91%) drop-shadow( 0px 0px 5px #f484b6);
|
||||
}
|
||||
.lds-ring div {
|
||||
border: 8px solid #1e1e2d;
|
||||
border-color: #1e1e2d transparent transparent transparent;
|
||||
}
|
||||
#progress-bar {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
background-color: #ea74ac;
|
||||
}
|
||||
.album-bottom {
|
||||
background-color: #ffffff;
|
||||
border-left: 0rem solid #ea74ac;
|
||||
}
|
||||
.album:hover .album-bottom {
|
||||
border-left: 0.25rem solid #ea74ac;
|
||||
}
|
||||
.track {
|
||||
border-bottom: 3px solid #f0f0f0;
|
||||
border-left: 0rem solid #ea74ac;
|
||||
}
|
||||
.track:hover {
|
||||
background-color: #fafafa;
|
||||
border-left: 0.25rem solid #ea74ac;
|
||||
}
|
||||
.slider {
|
||||
background-color: #ea74ac;
|
||||
}
|
||||
.slider:hover {
|
||||
filter: drop-shadow( 0px 0px 5px #ea74ac);
|
||||
}
|
||||
#git {
|
||||
filter: invert(100%);
|
||||
}
|
||||
#progress-state {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
#main {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
input {
|
||||
margin: 5px;
|
||||
width: 550px;
|
||||
max-width: 98%;
|
||||
padding: 15px;
|
||||
font-size: x-large;
|
||||
border: none;
|
||||
border-radius: 7px;
|
||||
transition: 0.1s border-bottom ease-out, 0.1s background-color ease-in-out;
|
||||
}
|
||||
|
||||
.album {
|
||||
padding: 15px;
|
||||
margin: 2px;
|
||||
font-size: large;
|
||||
border-radius: 10px 10px 0px 0px;
|
||||
transition: 0.1s border-left ease-out, 0.1s background-color ease-in-out;
|
||||
min-height: 96px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.small {
|
||||
font-size: medium;
|
||||
}
|
||||
.big {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#albums {
|
||||
margin-top: 20px;
|
||||
width: 600px;
|
||||
max-width: 98%;
|
||||
}
|
||||
#progress {
|
||||
width: 600px;
|
||||
max-width: 98%;
|
||||
}
|
||||
.album-image {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
border-radius: 10px;
|
||||
transition: 0.1s border ease-out, 0.1s box-shadow ease-out;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
}
|
||||
.album-image-wrapper {
|
||||
transition: 0.1s border ease-out;
|
||||
}
|
||||
.album-metadata {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
.metadata {
|
||||
height: 100%;
|
||||
}
|
||||
.link {
|
||||
cursor: pointer;
|
||||
transition: 0.1s color ease-out, 0.1s filter ease-out;
|
||||
}
|
||||
.album-download {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
transition: 0.1s filter ease-out;
|
||||
}
|
||||
.track .album-download {
|
||||
position: relative;
|
||||
top: 20px;
|
||||
}
|
||||
.lds-ring {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.lds-ring div {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin: 8px;
|
||||
border-radius: 50%;
|
||||
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
}
|
||||
.lds-ring div:nth-child(1) {
|
||||
animation-delay: -0.45s;
|
||||
}
|
||||
.lds-ring div:nth-child(2) {
|
||||
animation-delay: -0.3s;
|
||||
}
|
||||
.lds-ring div:nth-child(3) {
|
||||
animation-delay: -0.15s;
|
||||
}
|
||||
@keyframes lds-ring {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
#progress-bar {
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.album-bottom {
|
||||
padding: 0px;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
border-radius: 0px 0px 10px 10px;
|
||||
transition: 0.1s border-left ease-out;
|
||||
}
|
||||
.track {
|
||||
padding: 10px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
margin: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: large;
|
||||
transition: 0.05s background-color ease-out, 0.1s border-left ease-out;
|
||||
}
|
||||
.track:nth-last-child(1) {
|
||||
border-bottom: none;
|
||||
border-radius: 0px 0px 15px 15px;
|
||||
}
|
||||
|
||||
.track .album-download {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.track-download-wrapper {
|
||||
position: relative;
|
||||
bottom: 20px;
|
||||
height: 50%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#header {
|
||||
display: flex;
|
||||
align-items: left;
|
||||
justify-content: left;
|
||||
flex-direction: row;
|
||||
}
|
||||
#header > * {
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
#header .link {
|
||||
font-size: x-large;
|
||||
text-decoration: none;
|
||||
}
|
||||
#header img {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
/* The switch - the box around the slider */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-transition: .2s;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
-webkit-transition: .2s;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(26px);
|
||||
-ms-transform: translateX(26px);
|
||||
transform: translateX(26px);
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
.slider.round {
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#header-left {
|
||||
width: 100%;
|
||||
}
|
||||
#header-left > * {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
#progress-state {
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
border-radius: 10px;
|
||||
width: 80%;
|
||||
padding: 6px;
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
.album-downloading {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: rgb(255, 155, 155, 0.3);
|
||||
padding: 20px;
|
||||
border-radius: 15px;
|
||||
border: 3px solid rgb(255, 155, 155, 0.8);
|
||||
text-align: center;
|
||||
margin: 15px;
|
||||
width: 400px;
|
||||
display: none; /* this is changed by the js */
|
||||
}
|
||||
.error .big {
|
||||
font-size: x-large;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
import svelte from 'rollup-plugin-svelte';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import livereload from 'rollup-plugin-livereload';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import css from 'rollup-plugin-css-only';
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH;
|
||||
|
||||
function serve() {
|
||||
let server;
|
||||
|
||||
function toExit() {
|
||||
if (server) server.kill(0);
|
||||
}
|
||||
|
||||
return {
|
||||
writeBundle() {
|
||||
if (server) return;
|
||||
server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
|
||||
stdio: ['ignore', 'inherit', 'inherit'],
|
||||
shell: true
|
||||
});
|
||||
|
||||
process.on('SIGTERM', toExit);
|
||||
process.on('exit', toExit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
input: 'app/src/main.js',
|
||||
output: {
|
||||
sourcemap: true,
|
||||
format: 'iife',
|
||||
name: 'app',
|
||||
file: 'app/public/build/bundle.js'
|
||||
},
|
||||
plugins: [
|
||||
svelte({
|
||||
compilerOptions: {
|
||||
// enable run-time checks when not in production
|
||||
dev: !production
|
||||
}
|
||||
}),
|
||||
// we'll extract any component CSS out into
|
||||
// a separate file - better for performance
|
||||
css({ output: 'bundle.css' }),
|
||||
|
||||
// If you have external dependencies installed from
|
||||
// npm, you'll most likely need these plugins. In
|
||||
// some cases you'll need additional configuration -
|
||||
// consult the documentation for details:
|
||||
// https://github.com/rollup/plugins/tree/master/packages/commonjs
|
||||
resolve({
|
||||
browser: true,
|
||||
dedupe: ['svelte']
|
||||
}),
|
||||
commonjs(),
|
||||
|
||||
// In dev mode, call `npm run start` once
|
||||
// the bundle has been generated
|
||||
!production && serve(),
|
||||
|
||||
// Watch the `public` directory and refresh the
|
||||
// browser on changes when not in production
|
||||
!production && livereload('app/public'),
|
||||
|
||||
// If we're building for production (npm run build
|
||||
// instead of npm run dev), minify
|
||||
production && terser()
|
||||
],
|
||||
watch: {
|
||||
clearScreen: false
|
||||
}
|
||||
};
|
|
@ -24,6 +24,7 @@ if (config.server.proxy) {
|
|||
|
||||
app.use((req, res, next) => {
|
||||
logger.http(`${(config.server.proxy && req.headers['x-forwarded-for']) || req.connection.remoteAddress} ${req.method} ${req.originalUrl} `);
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
next();
|
||||
});
|
||||
|
||||
|
|