1.1.14 - importing and what not

This commit is contained in:
exttex
2021-01-25 21:00:06 +01:00
parent def6d5286d
commit b0ebe66d54
16 changed files with 500 additions and 51 deletions

View File

@ -27,8 +27,8 @@
permanent
fixed
app
mini-variant
expand-on-hover
:mini-variant='!this.$root.settings.sidebarOpen'
:expand-on-hover='!this.$root.settings.sidebarOpen'
><v-list nav dense>
<!-- Profile -->
@ -127,6 +127,16 @@
<v-list-item-title>{{$t('Downloads')}}</v-list-item-title>
</v-list-item>
<!-- Importer -->
<v-list-item link to='/importer'>
<v-list-item-icon>
<v-icon v-if='!$root.importer.done && !$root.importer.active'>mdi-import</v-icon>
<v-icon v-if='$root.importer.done' color='primary'>mdi-check</v-icon>
<v-progress-circular indeterminate style='top: -8px' size='42' v-if='$root.importer.active'></v-progress-circular>
</v-list-item-icon>
<v-list-item-title>{{$t('Importer')}}</v-list-item-title>
</v-list-item>
<!-- About -->
<v-list-item link to='/about'>
<v-list-item-icon>
@ -243,8 +253,7 @@
<v-spacer></v-spacer>
<!-- Volume -->
<v-col cols='auto' class='d-none d-sm-flex px-2' @click.stop>
<v-col cols='auto' class='d-none d-sm-flex px-2' @click.stop ref='volumeBar'>
<div style='width: 180px;' class='d-flex'>
<v-slider
dense
@ -445,6 +454,23 @@ export default {
}
},
async mounted() {
//Scroll on volume
this.$refs.volumeBar.addEventListener('wheel', e => {
//Volup
if (e.deltaY < 0) {
if (this.volume + 0.05 > 1)
this.volume = 1;
else
this.volume += 0.05;
} else {
//Voldown
if (this.volume - 0.05 < 0)
this.volume = 0;
else
this.volume -= 0.05;
}
});
//onClick for footer
this.$refs.footer.addEventListener('click', () => {
if (this.$root.track) this.showPlayer = true;

View File

@ -1,11 +1,11 @@
<template>
<div>
<v-card max-width='175px' max-height='210px' @click='play' :loading='loading' elevation='0' color='transparent'>
<v-card max-width='175px' max-height='220px' height='220px' @click='play' :loading='loading' elevation='0' color='transparent'>
<v-img :src='stl.cover.thumb'>
</v-img>
<div class='pa-2 text-subtitle-2 text-center text-truncate'>{{stl.title}}</div>
<div class='pa-2 text-subtitle-2'>{{stl.subtitle}}</div>
</v-card>
</div>

View File

@ -12,6 +12,7 @@ import Settings from '@/views/Settings.vue';
import DeezerPage from '@/views/DeezerPage.vue';
import DownloadsPage from '@/views/DownloadsPage.vue';
import About from '@/views/About.vue';
import Importer from '@/views/Importer.vue';
Vue.use(VueRouter);
@ -79,6 +80,10 @@ const routes = [
{
path: '/about',
component: About
},
{
path: '/importer',
component: Importer
}
];

View File

@ -146,5 +146,12 @@
"Collaborative": "Collaborative",
"Edit playlist": "Edit playlist",
"Save": "Save",
"Edit": "Edit"
"Edit": "Edit",
"Importer": "Importer",
"Enter URL": "Enter URL",
"Currently only Spotify is supported and limited to 100 tracks.": "Currently only Spotify is supported and limited to 100 tracks.",
"Import into playlist": "Import into playlist",
"Keep sidebar open": "Keep sidebar open",
"WARNING: Might require reload to work properly!": "WARNING: Might require reload to work properly!",
"An error occured, URL might be invalid or unsupported.": "An error occured, URL might be invalid or unsupported."
}

View File

@ -106,6 +106,14 @@ new Vue({
}
},
//Importer
importer: {
active: false,
done: false,
error: false,
tracks: []
},
//Used to prevent double listen logging
logListenId: null,
@ -586,6 +594,27 @@ new Vue({
this.seek(data.position);
});
//Importer
//Start
this.sockets.subscribe('importerInit', (data) => {
this.importer = data;
});
//New track imported
this.sockets.subscribe('importerTrack', (data) => {
this.importer.tracks.push(data);
});
//Mark as done
this.sockets.subscribe('importerDone', () => {
this.importer.active = false;
this.importer.done = true;
});
this.sockets.subscribe('importerError', () => {
this.importer.error = true;
this.importer.active = false;
this.importer.done = false;
});
r();
},
@ -605,6 +634,9 @@ new Vue({
document.addEventListener('keyup', (e) => {
//Don't handle keystrokes in text fields
if (e.target.tagName == "INPUT") return;
//Don't handle if specials
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;
//K toggle playback
if (e.code == "KeyK" || e.code == "Space") this.$root.toggle();
//L +10s (from YT)

View File

@ -100,23 +100,25 @@
</v-btn>
<!-- Volume -->
<v-slider
min='0.00'
:prepend-icon='$root.muted ? "mdi-volume-off" : "mdi-volume-high"'
max='1.00'
step='0.01'
v-model='$root.volume'
class='px-8'
style='padding-top: 2px;'
@change='updateVolume'
@click:prepend='$root.toggleMute()'
>
<template v-slot:append>
<div style='position: absolute; padding-top: 4px;'>
{{Math.round($root.volume * 100)}}%
</div>
</template>
</v-slider>
<div ref='volumeBar' style='width: 100%;'>
<v-slider
min='0.00'
:prepend-icon='$root.muted ? "mdi-volume-off" : "mdi-volume-high"'
max='1.00'
step='0.01'
v-model='$root.volume'
class='px-8'
style='padding-top: 2px;'
@change='updateVolume'
@click:prepend='$root.toggleMute()'
>
<template v-slot:append>
<div style='position: absolute; padding-top: 4px;'>
{{Math.round($root.volume * 100)}}%
</div>
</template>
</v-slider>
</div>
</div>
@ -328,6 +330,22 @@ export default {
}
},
mounted() {
//Scroll on volume
this.$refs.volumeBar.addEventListener('wheel', e => {
//Volup
if (e.deltaY < 0) {
if (this.$root.volume + 0.05 > 1)
this.$root.volume = 1;
else
this.$root.volume += 0.05;
} else {
//Voldown
if (this.$root.volume - 0.05 < 0)
this.$root.volume = 0;
else
this.$root.volume -= 0.05;
}
});
},
computed: {
},

View File

@ -0,0 +1,86 @@
<template>
<div>
<h1>{{$t("Importer")}}</h1><br>
<span class='text-h6'>
<v-icon right color='warning' class='mr-2'>mdi-alert</v-icon>
{{$t("Currently only Spotify is supported and limited to 100 tracks.")}}
</span>
<br>
<!-- URL entry and buttons -->
<div class='d-flex mt-4' v-if='!$root.importer.done && !$root.importer.active && !$root.importer.error'>
<v-text-field
v-model=input
:label='$t("Enter URL")'
:rules='[valid]'
></v-text-field>
<v-btn class='mx-2 mt-4' color='primary' :disabled='!valid' @click='start("import")'>
<v-icon left>mdi-playlist-plus</v-icon>
{{$t("Import into playlist")}}
</v-btn>
<v-btn class='mx-2 mt-4' color='green' :disabled='!valid' @click='start("download")'>
<v-icon left>mdi-download</v-icon>
{{$t("Download")}}
</v-btn>
</div>
<!-- Tracks -->
<div class='mt-4' v-if='$root.importer.done || $root.importer.active'>
<h2 class='mb-2'>Tracks:</h2>
<v-list>
<v-list-item v-for='(track, i) in $root.importer.tracks' :key='i'>
<v-list-item-avatar>
<v-img :src='track.art'></v-img>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>{{track.title}}</v-list-item-title>
<v-list-item-subtitle>{{track.artist}}</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-icon v-if='track.ok' color='green'>mdi-check</v-icon>
<v-icon v-if='!track.ok' color='red'></v-icon>
</v-list-item-action>
</v-list-item>
</v-list>
</div>
<!-- Error -->
<div v-if='$root.importer.error' class='text-center mt-4'>
<h2>{{$t("An error occured, URL might be invalid or unsupported.")}}</h2>
</div>
</div>
</template>
<script>
export default {
name: 'Importer',
data() {
return {
input: null,
}
},
methods: {
async start(type) {
await this.$axios.post('/import', {url: this.input, type});
}
},
computed: {
valid() {
let i = this.input || '';
return i.startsWith('https://open.spotify.com/playlist/') && !i.includes(' ');
}
},
mounted() {
},
destroyed() {
//If done
if (this.$root.importer.done || this.$root.importer.error) {
this.$root.importer.done = false;
this.$root.importer.active = false;
this.$root.importer.error = false;
this.$root.importer.tracks = [];
}
},
}
</script>

View File

@ -144,7 +144,6 @@
<v-list-item-title class='pl-2'>{{$t("Select primary color")}}</v-list-item-title>
</v-list-item-content>
</v-list-item>
<!-- Autocomplete -->
<v-list-item>
<v-list-item-action>
@ -154,6 +153,17 @@
<v-list-item-title>{{$t("Show autocomplete in search")}}</v-list-item-title>
</v-list-item-content>
</v-list-item>
<!-- Keep sidebar open -->
<v-list-item>
<v-list-item-action>
<v-checkbox v-model='$root.settings.sidebarOpen' class='pl-2'></v-checkbox>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>{{$t("Keep sidebar open")}}</v-list-item-title>
<v-list-item-subtitle>{{$t("WARNING: Might require reload to work properly!")}}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<!-- Accounts -->
<v-subheader>{{$t("Integrations")}}</v-subheader>