mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 12:33:03 +00:00
Use gunicorn instead of Werkzeug and 32 more very minor changes (#35)
This commit is contained in:
@@ -32,9 +32,16 @@ import perks from "../../composables/perks.js";
|
||||
import { AlbumInfo } from "../../interfaces.js";
|
||||
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
||||
import { playSources } from "../../composables/enums";
|
||||
|
||||
const props = defineProps<{
|
||||
album: AlbumInfo;
|
||||
}>();
|
||||
|
||||
function extrackColors() {
|
||||
|
||||
}
|
||||
|
||||
extrackColors();
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -47,9 +54,9 @@ const props = defineProps<{
|
||||
grid-template-columns: 15rem 1fr;
|
||||
padding: 1rem;
|
||||
height: 100%;
|
||||
background-color: $gray4;
|
||||
background-image: linear-gradient(37deg, $black 20%, $gray5, $black 90%);
|
||||
|
||||
background-color: $black;
|
||||
background-color: #000000;
|
||||
background-image: linear-gradient(147deg, #436a91 0%, #2c3e50 74%);
|
||||
.art {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="folder">
|
||||
<div class="table rounded" v-if="props.tracks.length">
|
||||
<div class="table rounded" v-if="tracks.length">
|
||||
<div class="thead">
|
||||
<div class="index"></div>
|
||||
<div class="track-header">Track</div>
|
||||
@@ -10,7 +10,7 @@
|
||||
</div>
|
||||
<div class="songlist">
|
||||
<SongItem
|
||||
v-for="(song, index) in props.tracks"
|
||||
v-for="(song, index) in tracks"
|
||||
:key="song.trackid"
|
||||
:song="song"
|
||||
:index="index + 1"
|
||||
@@ -20,7 +20,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="props.tracks.length === 0 && search_query">
|
||||
<div v-else-if="tracks.length === 0 && search_query">
|
||||
<div class="no-results">
|
||||
<div class="text">Nothing down here 😑</div>
|
||||
</div>
|
||||
@@ -49,9 +49,13 @@ const props = defineProps<{
|
||||
let route = useRoute().name;
|
||||
const search_query = state.search_query;
|
||||
|
||||
/**
|
||||
* Plays a clicked track and updates the queue
|
||||
*
|
||||
* @param track Track object
|
||||
*/
|
||||
function updateQueue(track: Track) {
|
||||
switch (route) {
|
||||
// check which route the play request come from
|
||||
case "FolderView":
|
||||
queue.playFromFolder(props.path, props.tracks);
|
||||
queue.play(track);
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
></div>
|
||||
</div>
|
||||
<div id="bitrate">
|
||||
<span v-if="track.bitrate > 330"
|
||||
>FLAC • {{ track.bitrate }}</span
|
||||
>
|
||||
<span v-else>MP3 | {{ track.bitrate }}</span>
|
||||
<span v-if="track.bitrate > 1500">MASTER</span>
|
||||
<span v-else-if="track.bitrate > 330">FLAC</span>
|
||||
<span v-else>MP3</span>
|
||||
• {{ track.bitrate }}
|
||||
</div>
|
||||
<div class="title ellip">{{ props.track.title }}</div>
|
||||
<div class="separator no-border"></div>
|
||||
|
||||
@@ -84,7 +84,7 @@ const queue = useQStore();
|
||||
position: absolute;
|
||||
font-size: 0.75rem;
|
||||
width: max-content;
|
||||
padding: 0.2rem;
|
||||
padding: 0.2rem .35rem;
|
||||
top: 13.25rem;
|
||||
left: 1.5rem;
|
||||
background-color: $black;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
]"
|
||||
v-for="notif in notifStore.notifs"
|
||||
>
|
||||
<div>{{ notif.text }}</div>
|
||||
<div class="ellip">{{ notif.text }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
<div class="last-updated">
|
||||
<span class="status"
|
||||
>Last updated {{ props.info.lastUpdated }} | </span
|
||||
>Last updated {{ props.info.lastUpdated }}  |  </span
|
||||
>
|
||||
<span class="edit" @click="editPlaylist">Edit</span>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="right-search">
|
||||
<Options />
|
||||
<!-- </div> -->
|
||||
<div class="scrollable" ref="search_thing">
|
||||
<TracksGrid
|
||||
v-if="tracks.tracks.length"
|
||||
:more="tracks.more"
|
||||
:tracks="tracks.tracks"
|
||||
:query="search.query"
|
||||
@loadMore="loadMoreTracks"
|
||||
/>
|
||||
<div class="separator no-border" v-if="tracks.tracks.length"></div>
|
||||
@@ -49,8 +49,7 @@
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from "@vue/reactivity";
|
||||
|
||||
import state from "@/composables/state";
|
||||
import state from "../../composables/state";
|
||||
import searchMusic from "@/composables/searchMusic.js";
|
||||
import useDebouncedRef from "@/composables/useDebouncedRef";
|
||||
import AlbumGrid from "@/components/Search/AlbumGrid.vue";
|
||||
@@ -83,8 +82,6 @@ const artists = reactive({
|
||||
more: false,
|
||||
});
|
||||
|
||||
const query = useDebouncedRef("", 600);
|
||||
|
||||
function scrollSearchThing() {
|
||||
search_thing.value.scroll({
|
||||
top: search_thing.value.scrollTop + 330,
|
||||
|
||||
@@ -6,13 +6,10 @@
|
||||
id="search"
|
||||
class="rounded"
|
||||
v-model="search.query"
|
||||
placeholder="Search"
|
||||
placeholder="Search your library"
|
||||
type="text"
|
||||
@keyup.backspace="removeLastFilter"
|
||||
/>
|
||||
<div class="_loader">
|
||||
<Loader />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -68,23 +65,15 @@ function removeLastFilter() {
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
border: none;
|
||||
border: solid 1px $primary;
|
||||
line-height: 2.25rem;
|
||||
background-color: transparent;
|
||||
color: rgb(255, 255, 255);
|
||||
background-color: $gray5;
|
||||
color: inherit;
|
||||
font-size: 1rem;
|
||||
outline: none;
|
||||
transition: all 0.5s ease;
|
||||
padding-left: 0.75rem;
|
||||
outline: 2px solid transparent;
|
||||
|
||||
&:focus {
|
||||
transition: all 0.5s ease;
|
||||
color: rgb(255, 255, 255);
|
||||
outline: none;
|
||||
|
||||
&::placeholder {
|
||||
display: none;
|
||||
}
|
||||
outline: solid $accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +1,59 @@
|
||||
<template>
|
||||
<div id="playing-from" class="rounded" @click="goTo">
|
||||
<div class="h">
|
||||
<div class="icon image" :class="from.type"></div>
|
||||
<div class="icon image" :class="from.icon"></div>
|
||||
Playing from
|
||||
</div>
|
||||
<div class="name">
|
||||
<div id="to">
|
||||
{{ from.name }}
|
||||
{{ from.text }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { fromFolder, fromAlbum, fromPlaylist } from "../../../interfaces";
|
||||
import { fromFolder, fromAlbum, fromPlaylist, fromSearch } from "../../../interfaces";
|
||||
import { FromOptions } from "../../../composables/enums";
|
||||
import { useRouter } from "vue-router";
|
||||
import { computed } from "@vue/reactivity";
|
||||
|
||||
const props = defineProps<{
|
||||
from: fromFolder | fromAlbum | fromPlaylist;
|
||||
from: fromFolder | fromAlbum | fromPlaylist | fromSearch;
|
||||
}>();
|
||||
|
||||
interface from {
|
||||
type: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
const from = computed((): from => {
|
||||
switch (props.from.type) {
|
||||
case undefined:
|
||||
return {
|
||||
type: "album",
|
||||
name: "Welcome to Alice",
|
||||
icon: "album",
|
||||
text: "Welcome to Alice",
|
||||
};
|
||||
case FromOptions.folder:
|
||||
return {
|
||||
type: "folder",
|
||||
name: props.from.name,
|
||||
icon: "folder",
|
||||
text: props.from.name,
|
||||
};
|
||||
case FromOptions.album:
|
||||
return {
|
||||
type: "album",
|
||||
name: props.from.name,
|
||||
icon: "album",
|
||||
text: props.from.name,
|
||||
};
|
||||
case FromOptions.playlist:
|
||||
return {
|
||||
type: "playlist",
|
||||
name: props.from.name,
|
||||
icon: "playlist",
|
||||
text: props.from.name,
|
||||
};
|
||||
case FromOptions.search:
|
||||
return {
|
||||
icon: "search",
|
||||
text: `Search results for: "${props.from.query}"`
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="morexx">
|
||||
<button @click="loadMore" class="">
|
||||
<div @click="loadMore" class="btn circular">
|
||||
<div class="text">Load More</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -22,19 +22,18 @@ function loadMore() {
|
||||
place-items: center;
|
||||
margin-top: $small;
|
||||
|
||||
button {
|
||||
border-radius: 1.5rem;
|
||||
.btn {
|
||||
height: 2.5rem;
|
||||
width: 15rem;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
transition: all 0.5s ease;
|
||||
color: rgba(255, 255, 255, 0.87) !important;
|
||||
background-color: $accent;
|
||||
// border: solid 1px $gray;
|
||||
background-image: linear-gradient(37deg, $red, $blue);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: $blue !important;
|
||||
width: 50%;
|
||||
width: 12rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +1,35 @@
|
||||
<template>
|
||||
<div class="tracks-results" v-if="tracks">
|
||||
<div class="heading">Tracks</div>
|
||||
<div class="items">
|
||||
<table>
|
||||
<tbody>
|
||||
<TrackItem
|
||||
v-for="track in props.tracks"
|
||||
:key="track.trackid"
|
||||
:track="track"
|
||||
:isPlaying="queue.playing"
|
||||
:isCurrent="queue.current.trackid == track.trackid"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
<LoadMore v-if="more" @loadMore="loadMore" />
|
||||
</div>
|
||||
<TransitionGroup class="items" name="list">
|
||||
<TrackItem
|
||||
v-for="track in tracks"
|
||||
:key="track.trackid"
|
||||
:track="track"
|
||||
:isPlaying="queue.playing"
|
||||
:isCurrent="queue.current.trackid == track.trackid"
|
||||
:isSearchTrack="true"
|
||||
@PlayThis="updateQueue"
|
||||
/>
|
||||
</TransitionGroup>
|
||||
<LoadMore v-if="more" @loadMore="loadMore" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import LoadMore from "./LoadMore.vue";
|
||||
import TrackItem from "../shared/TrackItem.vue";
|
||||
import useQStore from "../../stores/queue";
|
||||
import { Track } from "../../interfaces";
|
||||
|
||||
let counter = 0;
|
||||
const queue = useQStore();
|
||||
const props = defineProps({
|
||||
tracks: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
more: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
tracks: Track[];
|
||||
more: boolean;
|
||||
query: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(["loadMore"]);
|
||||
|
||||
@@ -42,6 +37,12 @@ function loadMore() {
|
||||
counter += 5;
|
||||
emit("loadMore", counter);
|
||||
}
|
||||
|
||||
function updateQueue(track: Track) {
|
||||
console.log(props.query);
|
||||
queue.playFromSearch(props.query, props.tracks);
|
||||
queue.play(track);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -49,6 +50,16 @@ function loadMore() {
|
||||
border-radius: 0.5rem;
|
||||
padding: $small;
|
||||
border: 1px solid $gray3;
|
||||
// background: ;
|
||||
|
||||
.list-enter-active,
|
||||
.list-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
transition-delay: 0.5s;
|
||||
}
|
||||
.list-enter-from,
|
||||
.list-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(2rem);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<div class="play">
|
||||
<PlayBtnRect />
|
||||
</div>
|
||||
<Option v-if="$route.name === 'FolderView'" />
|
||||
|
||||
<div class="fname">
|
||||
<div class="icon image"></div>
|
||||
<div class="ellip">
|
||||
@@ -35,6 +37,7 @@ import NavButtons from "./NavButtons.vue";
|
||||
import Loader from "../shared/Loader.vue";
|
||||
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
||||
import Search from "./Search.vue";
|
||||
import Option from "../shared/Option.vue";
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -49,7 +52,6 @@ import Search from "./Search.vue";
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $small;
|
||||
|
||||
.info {
|
||||
.title {
|
||||
@@ -59,26 +61,32 @@ import Search from "./Search.vue";
|
||||
|
||||
.folder {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
gap: $small;
|
||||
|
||||
.playbtnrect {
|
||||
height: 2.25rem;
|
||||
}
|
||||
|
||||
.drop-btn {
|
||||
width: 2.25rem;
|
||||
|
||||
.drop-icon {
|
||||
height: 2.25rem;
|
||||
width: 2.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.fname {
|
||||
position: relative;
|
||||
padding-left: 2.25rem;
|
||||
padding-left: 0.5rem;
|
||||
background-color: $gray4;
|
||||
border-radius: $small;
|
||||
height: 2.25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: $small;
|
||||
gap: 0.25rem;
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
left: $small;
|
||||
top: $small;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
background-image: url("../../assets/icons/folder.fill.svg");
|
||||
@@ -96,6 +104,8 @@ import Search from "./Search.vue";
|
||||
|
||||
.right {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: $small;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -91,6 +91,7 @@ const props = defineProps<{
|
||||
|
||||
.name {
|
||||
text-transform: capitalize;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.count {
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<template>
|
||||
<div class="loaderx" :class="{ loader: loading, not_loader: !loading }">
|
||||
<div v-if="!loading">🦋</div>
|
||||
<div
|
||||
class="loaderx"
|
||||
:class="{ loader: loader.loading, not_loader: !loader.loading }"
|
||||
>
|
||||
<div v-if="!loader.loading">🦋</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import state from "@/composables/state";
|
||||
|
||||
const loading = state.loading;
|
||||
import useLoaderStore from "../../stores/loader";
|
||||
const loader = useLoaderStore();
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -17,9 +17,8 @@ import { ContextSrc } from "../../composables/enums";
|
||||
let elem: DOMRect;
|
||||
const clicked = ref(false);
|
||||
|
||||
const props = defineProps<{
|
||||
defineProps<{
|
||||
src?: string;
|
||||
color?: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -45,7 +44,6 @@ function showDropdown(e: Event) {
|
||||
<style lang="scss">
|
||||
.drop-btn {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
background-color: $accent;
|
||||
transition: all 0.5s ease-in-out;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -20,14 +20,6 @@
|
||||
</div>
|
||||
<div @click="emitUpdate(props.song)">
|
||||
<span class="ellip title">{{ props.song.title }}</span>
|
||||
<div class="artist ellip">
|
||||
<span
|
||||
v-for="artist in perks.putCommas(props.song.artists)"
|
||||
:key="artist"
|
||||
>
|
||||
{{ artist }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="song-artists">
|
||||
@@ -200,17 +192,6 @@ function emitUpdate(track: Track) {
|
||||
.title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.artist {
|
||||
display: none;
|
||||
font-size: 0.8rem;
|
||||
color: rgba(255, 255, 255, 0.719);
|
||||
cursor: pointer;
|
||||
|
||||
@include phone-only {
|
||||
display: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
|
||||
Reference in New Issue
Block a user