mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 20:43:04 +00:00
Use gunicorn instead of Werkzeug and 32 more very minor changes (#35)
This commit is contained in:
+4
-3
@@ -9,9 +9,9 @@
|
||||
><div class="logo"></div
|
||||
></router-link>
|
||||
</div>
|
||||
<Navigation :collapsed="collapsed" />
|
||||
<Navigation />
|
||||
<div class="l-album-art">
|
||||
<nowPlaying :collapsed="collapsed" />
|
||||
<nowPlaying />
|
||||
</div>
|
||||
</div>
|
||||
<NavBar />
|
||||
@@ -40,6 +40,7 @@ import ContextMenu from "./components/contextMenu.vue";
|
||||
import Modal from "./components/modal.vue";
|
||||
import Notification from "./components/Notification.vue";
|
||||
import useQStore from "./stores/queue";
|
||||
import shortcuts from "./composables/keyboard";
|
||||
|
||||
const context_store = useContextStore();
|
||||
const queue = useQStore();
|
||||
@@ -48,7 +49,7 @@ queue.readQueueFromLocalStorage();
|
||||
|
||||
const RightSideBar = Main;
|
||||
|
||||
const collapsed = ref(false);
|
||||
shortcuts(queue);
|
||||
|
||||
const app_dom = document.getElementById("app");
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -22,4 +22,5 @@ export enum ContextSrc {
|
||||
PHeader = "PHeader",
|
||||
Track = "Track",
|
||||
AHeader = "AHeader",
|
||||
FHeader = "FHeader"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import { Store } from "pinia";
|
||||
|
||||
let key_down_fired = false;
|
||||
|
||||
function focusSearchBox() {
|
||||
const elem = document.getElementById("search");
|
||||
|
||||
elem.focus();
|
||||
}
|
||||
|
||||
export default function (queue: any) {
|
||||
window.addEventListener("keydown", (e: any) => {
|
||||
let target = e.target;
|
||||
let ctrlKey = e.ctrlKey;
|
||||
|
||||
switch (e.key) {
|
||||
case "ArrowRight":
|
||||
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") return;
|
||||
|
||||
{
|
||||
if (!key_down_fired) {
|
||||
key_down_fired = true;
|
||||
|
||||
setTimeout(() => {
|
||||
key_down_fired = false;
|
||||
}, 1000);
|
||||
|
||||
queue.playNext();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "ArrowLeft":
|
||||
{
|
||||
if (!key_down_fired) {
|
||||
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") return;
|
||||
|
||||
key_down_fired = true;
|
||||
|
||||
queue.playPrev();
|
||||
|
||||
setTimeout(() => {
|
||||
key_down_fired = false;
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case " ":
|
||||
{
|
||||
if (!key_down_fired) {
|
||||
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") return;
|
||||
e.preventDefault();
|
||||
key_down_fired = true;
|
||||
|
||||
queue.playPause();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "f": {
|
||||
if (!key_down_fired) {
|
||||
if (!ctrlKey) return;
|
||||
e.preventDefault();
|
||||
focusSearchBox();
|
||||
|
||||
key_down_fired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("keyup", () => {
|
||||
key_down_fired = false;
|
||||
});
|
||||
@@ -35,81 +35,6 @@ function getElem(identifier, type) {
|
||||
}
|
||||
}
|
||||
|
||||
function focusSearchBox() {
|
||||
const elem = getElem("search", "id");
|
||||
|
||||
elem.focus();
|
||||
}
|
||||
|
||||
let key_down_fired = false;
|
||||
|
||||
window.addEventListener("keydown", (e) => {
|
||||
let target = e.target;
|
||||
let ctrlKey = e.ctrlKey;
|
||||
|
||||
switch (e.key) {
|
||||
case "ArrowRight":
|
||||
if (target.tagName === "INPUT") return;
|
||||
|
||||
{
|
||||
if (!key_down_fired) {
|
||||
key_down_fired = true;
|
||||
|
||||
setTimeout(() => {
|
||||
key_down_fired = false;
|
||||
}, 1000);
|
||||
|
||||
// playAudio.playNext();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "ArrowLeft":
|
||||
{
|
||||
if (!key_down_fired) {
|
||||
if (target.tagName === "INPUT") return;
|
||||
|
||||
key_down_fired = true;
|
||||
|
||||
// playAudio.playPrev();
|
||||
|
||||
setTimeout(() => {
|
||||
key_down_fired = false;
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case " ":
|
||||
{
|
||||
if (!key_down_fired) {
|
||||
if (target.tagName === "INPUT") return;
|
||||
e.preventDefault();
|
||||
key_down_fired = true;
|
||||
|
||||
// playAudio.playPause();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "f": {
|
||||
if (!key_down_fired) {
|
||||
if (!ctrlKey) return;
|
||||
e.preventDefault();
|
||||
focusSearchBox();
|
||||
|
||||
key_down_fired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("keyup", () => {
|
||||
key_down_fired = false;
|
||||
});
|
||||
|
||||
function formatSeconds(seconds) {
|
||||
// check if there are arguments
|
||||
|
||||
|
||||
@@ -80,6 +80,11 @@ interface fromPlaylist {
|
||||
playlistid: string;
|
||||
}
|
||||
|
||||
interface fromSearch {
|
||||
type: FromOptions;
|
||||
query: string;
|
||||
}
|
||||
|
||||
export {
|
||||
Track,
|
||||
Folder,
|
||||
@@ -91,4 +96,5 @@ export {
|
||||
fromFolder,
|
||||
fromAlbum,
|
||||
fromPlaylist,
|
||||
fromSearch,
|
||||
};
|
||||
|
||||
+1
-1
@@ -21,9 +21,9 @@ export default defineStore("album", {
|
||||
this.tracks = tracks.tracks;
|
||||
this.info = tracks.info;
|
||||
this.artists = artists;
|
||||
this.bio = null;
|
||||
},
|
||||
fetchBio(title: string, albumartist: string) {
|
||||
this.bio = null;
|
||||
getAlbumBio(title, albumartist).then((bio) => {
|
||||
this.bio = bio;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
export default defineStore("Loader", {
|
||||
state: () => ({
|
||||
loading: false,
|
||||
duration: 0,
|
||||
}),
|
||||
actions: {
|
||||
startLoading() {
|
||||
this.loading = true;
|
||||
this.duration = new Date().getTime();
|
||||
},
|
||||
stopLoading() {
|
||||
const diff = new Date().getTime() - this.duration;
|
||||
console.log(diff);
|
||||
|
||||
if (diff <= 250) {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
}, 250 - diff);
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
+15
-1
@@ -1,6 +1,12 @@
|
||||
import { defineStore } from "pinia";
|
||||
import state from "../composables/state";
|
||||
import { Track, fromFolder, fromAlbum, fromPlaylist } from "../interfaces";
|
||||
import {
|
||||
Track,
|
||||
fromFolder,
|
||||
fromAlbum,
|
||||
fromPlaylist,
|
||||
fromSearch,
|
||||
} from "../interfaces";
|
||||
import notif from "../composables/mediaNotification";
|
||||
import { FromOptions } from "../composables/enums";
|
||||
|
||||
@@ -181,6 +187,14 @@ export default defineStore("Queue", {
|
||||
playlistid: pid,
|
||||
};
|
||||
|
||||
this.setNewQueue(tracks);
|
||||
},
|
||||
playFromSearch(query: string, tracks: Track[]) {
|
||||
this.from = <fromSearch>{
|
||||
type: FromOptions.search,
|
||||
query: query,
|
||||
};
|
||||
|
||||
this.setNewQueue(tracks);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ export default defineStore("tabs", {
|
||||
current: tablist.home,
|
||||
}),
|
||||
actions: {
|
||||
changeTab(tab) {
|
||||
changeTab(tab: string) {
|
||||
if (tab === this.tabs.queue) {
|
||||
setTimeout(() => {
|
||||
perks.focusCurrent();
|
||||
@@ -20,19 +20,21 @@ import FolderList from "@/components/FolderView/FolderList.vue";
|
||||
|
||||
import useFStore from "../stores/folder";
|
||||
import state from "../composables/state";
|
||||
import useLoaderStore from "../stores/loader";
|
||||
|
||||
const loader = useLoaderStore();
|
||||
const FStore = useFStore();
|
||||
|
||||
const scrollable = ref(null);
|
||||
|
||||
onBeforeRouteUpdate((to) => {
|
||||
state.loading.value = true;
|
||||
loader.startLoading();
|
||||
FStore.fetchAll(to.params.path)
|
||||
.then(() => {
|
||||
scrollable.value.scrollTop = 0;
|
||||
})
|
||||
.then(() => {
|
||||
state.loading.value = false;
|
||||
loader.stopLoading();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user