mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
rewrite queue page to use songlist
+ add nav components to queue page + revert tooltip to undo handling updates - I can't find a viable solution to the updates problem
This commit is contained in:
@@ -67,6 +67,7 @@ button {
|
||||
justify-content: center;
|
||||
height: 2.25rem;
|
||||
background: linear-gradient(70deg, $gray3, $gray2);
|
||||
padding: 0 $small;
|
||||
|
||||
&:hover {
|
||||
background-image: linear-gradient(70deg, $darkestblue, $darkblue);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="table"
|
||||
class="table border rounded"
|
||||
v-if="tracks.length"
|
||||
ref="tracklistElem"
|
||||
:class="{
|
||||
@@ -39,13 +39,13 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useElementSize } from "@vueuse/core";
|
||||
import { computed } from "@vue/reactivity";
|
||||
|
||||
import SongItem from "../shared/SongItem.vue";
|
||||
|
||||
import { Routes } from "@/composables/enums";
|
||||
import { Track } from "@/interfaces";
|
||||
import useQStore from "@/stores/queue";
|
||||
import { computed } from "@vue/reactivity";
|
||||
|
||||
const queue = useQStore();
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<span>Shuffle</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="right"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -37,20 +36,11 @@ const queue = useQueueStore();
|
||||
}
|
||||
|
||||
.action {
|
||||
padding: $smaller;
|
||||
padding-right: $small;
|
||||
padding-left: $smaller;
|
||||
|
||||
svg {
|
||||
transform: scale(0.8);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-more {
|
||||
padding-right: $smaller;
|
||||
|
||||
svg {
|
||||
transform: scale(1.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
<Folder v-if="$route.name == Routes.folder" :subPaths="subPaths" />
|
||||
<SearchTitle v-if="$route.name == Routes.search" />
|
||||
<PlaylistsTitle v-if="$route.name == Routes.playlists" />
|
||||
<QueueTitle v-if="$route.name == Routes.queue" />
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<!--
|
||||
<div class="center rounded">
|
||||
<Loader />
|
||||
</div> -->
|
||||
@@ -23,21 +24,24 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import NavButtons from "./NavButtons.vue";
|
||||
import Loader from "../shared/Loader.vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { ref, watch } from "vue";
|
||||
import { Routes } from "@/composables/enums";
|
||||
import { createSubPaths } from "@/utils";
|
||||
import { useRoute } from "vue-router";
|
||||
import { computed } from "@vue/reactivity";
|
||||
|
||||
import { subPath } from "@/interfaces";
|
||||
import useNavStore from "@/stores/nav";
|
||||
import { createSubPaths } from "@/utils";
|
||||
import { Routes } from "@/composables/enums";
|
||||
|
||||
import NavButtons from "./NavButtons.vue";
|
||||
// import Loader from "../shared/Loader.vue";
|
||||
|
||||
import Folder from "./Titles/Folder.vue";
|
||||
import SimpleTitle from "./Titles/SimpleTitle.vue";
|
||||
import APTitle from "./Titles/APTitle.vue";
|
||||
import useNavStore from "@/stores/nav";
|
||||
|
||||
import { computed } from "@vue/reactivity";
|
||||
import SearchTitle from "./Titles/SearchTitle.vue";
|
||||
import PlaylistsTitle from "./Titles/PlaylistsTitle.vue";
|
||||
import QueueTitle from "./Titles/QueueTitle.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const nav = useNavStore();
|
||||
@@ -53,7 +57,7 @@ const showAPTitle = computed(() => {
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
(newRoute: string) => {
|
||||
(newRoute) => {
|
||||
switch (newRoute) {
|
||||
case Routes.folder:
|
||||
let oldpath = "";
|
||||
@@ -90,6 +94,7 @@ watch(
|
||||
display: grid;
|
||||
grid-template-columns: max-content 1fr;
|
||||
gap: 1rem;
|
||||
height: 2.25rem;
|
||||
|
||||
.info {
|
||||
margin: auto 0;
|
||||
|
||||
@@ -20,18 +20,17 @@ import ArrowSvg from "../../assets/icons/right-arrow.svg";
|
||||
gap: 1rem;
|
||||
padding-right: 1.25rem;
|
||||
border-right: 1px solid $gray3;
|
||||
width: 100%;
|
||||
width: max-content;
|
||||
height: 100%;
|
||||
|
||||
& > * {
|
||||
width: 2.25rem;
|
||||
background-color: $gray3;
|
||||
padding: $small;
|
||||
height: 100%;
|
||||
aspect-ratio: 1;
|
||||
border-radius: $medium;
|
||||
|
||||
svg {
|
||||
margin: auto;
|
||||
}
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.back {
|
||||
|
||||
@@ -19,7 +19,7 @@ const things = computed(() => {
|
||||
const route = useRoute();
|
||||
let thing = {
|
||||
text: "",
|
||||
store: null,
|
||||
store: null as any,
|
||||
source: playSources.album,
|
||||
};
|
||||
|
||||
@@ -38,7 +38,6 @@ const things = computed(() => {
|
||||
store: usePStore,
|
||||
};
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
return thing;
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div class="nav-queue-title">
|
||||
<div class="first noscroll">
|
||||
<router-link :to="(getSourceUrlParams())">
|
||||
<button>Go to source</button>
|
||||
</router-link>
|
||||
<div class="playing-from">
|
||||
<div class="border rounded-sm pad-sm">
|
||||
<b class="ellip">{{ getSourceName() }}</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<QueueActions />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import QueueActions from "@/components/RightSideBar/Queue/QueueActions.vue";
|
||||
import { FromOptions, Routes } from "@/composables/enums";
|
||||
import useQueueStore from "@/stores/queue";
|
||||
import { RouteLocationRaw, RouteRecordRaw } from "vue-router";
|
||||
|
||||
const queue = useQueueStore();
|
||||
|
||||
const { from: source } = queue;
|
||||
|
||||
function getSourceName(): RouteLocationRaw {
|
||||
switch (source.type) {
|
||||
case FromOptions.album:
|
||||
return source.name;
|
||||
|
||||
case FromOptions.folder:
|
||||
return source.name;
|
||||
|
||||
case FromOptions.playlist:
|
||||
return source.name;
|
||||
|
||||
case FromOptions.search:
|
||||
return `Search for: "${source.query}"`;
|
||||
|
||||
default:
|
||||
return "Ghost source";
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceUrlParams() {
|
||||
switch (source.type) {
|
||||
case FromOptions.album:
|
||||
return {
|
||||
name: Routes.album,
|
||||
params: {
|
||||
hash: source.hash,
|
||||
},
|
||||
};
|
||||
case FromOptions.folder:
|
||||
return {
|
||||
name: Routes.folder,
|
||||
params: {
|
||||
path: source.path,
|
||||
},
|
||||
};
|
||||
case FromOptions.playlist:
|
||||
return {
|
||||
name: Routes.playlist,
|
||||
params: {
|
||||
pid: source.playlistid,
|
||||
},
|
||||
};
|
||||
case FromOptions.search:
|
||||
return {
|
||||
name: Routes.search,
|
||||
params: {
|
||||
query: source.query,
|
||||
},
|
||||
};
|
||||
|
||||
default:
|
||||
return "/";
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.nav-queue-title {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr max-content;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
|
||||
.first {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: max-content 1fr;
|
||||
gap: 1rem;
|
||||
|
||||
.playing-from {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $small;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.queue-actions {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -24,9 +24,7 @@ defineProps<{
|
||||
|
||||
<style lang="scss">
|
||||
.play-btn {
|
||||
height: 100%;
|
||||
aspect-ratio: 1;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -76,7 +76,6 @@ const imguri = paths.images.thumb;
|
||||
const options_button_clicked = ref(false);
|
||||
|
||||
const artisttitle = ref<HTMLElement | null>(null);
|
||||
const tooltip = ref<HTMLElement | null>(null);
|
||||
|
||||
const props = defineProps<{
|
||||
track: Track;
|
||||
@@ -107,13 +106,14 @@ function showMenu(e: Event) {
|
||||
height: 3.75rem;
|
||||
gap: 1rem;
|
||||
user-select: none;
|
||||
// background-color: $gray;
|
||||
|
||||
// &:nth-child(odd) {
|
||||
// background-color: rgba(26, 26, 26, 0.068);
|
||||
// }
|
||||
|
||||
&:hover {
|
||||
background-color: $gray4;
|
||||
|
||||
.options-icon {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.song-album {
|
||||
@@ -138,7 +138,6 @@ function showMenu(e: Event) {
|
||||
opacity: 0.5;
|
||||
font-size: 0.8rem;
|
||||
width: 100%;
|
||||
// margin-left: $small;
|
||||
}
|
||||
|
||||
.song-duration {
|
||||
@@ -151,7 +150,6 @@ function showMenu(e: Event) {
|
||||
}
|
||||
|
||||
.options-icon {
|
||||
opacity: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -160,7 +158,7 @@ function showMenu(e: Event) {
|
||||
|
||||
svg {
|
||||
transition: all 0.2s ease-in;
|
||||
transform: rotate(90deg);
|
||||
// transform: rotate(90deg);
|
||||
stroke: $track-btn-svg;
|
||||
|
||||
circle {
|
||||
|
||||
+37
-50
@@ -1,4 +1,4 @@
|
||||
import { Directive, Ref, ref } from "vue";
|
||||
import { Directive } from "vue";
|
||||
import { createPopper } from "@popperjs/core";
|
||||
|
||||
let tooltip: HTMLElement;
|
||||
@@ -11,60 +11,47 @@ function hideTooltip() {
|
||||
tooltip.style.visibility = "hidden";
|
||||
}
|
||||
|
||||
function handleHover(el: HTMLElement, text: string, handleOthers = true) {
|
||||
let isHovered = false;
|
||||
|
||||
el.addEventListener("mouseover", () => {
|
||||
isHovered = true;
|
||||
tooltip.innerText = text;
|
||||
|
||||
setTimeout(() => {
|
||||
if (isHovered) {
|
||||
tooltip.style.visibility = "visible";
|
||||
|
||||
createPopper(el, tooltip, {
|
||||
placement: "top",
|
||||
modifiers: [
|
||||
{
|
||||
name: "offset",
|
||||
options: {
|
||||
offset: [0, 10],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hide",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
function handleHide() {
|
||||
["mouseout", "click"].forEach((event) => {
|
||||
el.addEventListener(event, () => {
|
||||
isHovered = false;
|
||||
hideTooltip();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
handleOthers ? handleHide() : null;
|
||||
});
|
||||
}
|
||||
let isHovered = ref(false);
|
||||
|
||||
export default {
|
||||
mounted(el: HTMLElement, binding) {
|
||||
mounted(el, binding) {
|
||||
let isHovered = false;
|
||||
|
||||
if (tooltip === undefined) {
|
||||
tooltip = getTooltip();
|
||||
}
|
||||
|
||||
handleHover(el, binding.value);
|
||||
},
|
||||
updated(el, binding) {
|
||||
el.removeEventListener("mouseover", () => {});
|
||||
handleHover(el, binding.value, false);
|
||||
el.addEventListener("mouseover", () => {
|
||||
isHovered = true;
|
||||
|
||||
setTimeout(() => {
|
||||
if (isHovered) {
|
||||
tooltip.innerText = binding.value;
|
||||
tooltip.style.visibility = "visible";
|
||||
|
||||
createPopper(el, tooltip, {
|
||||
placement: "top",
|
||||
modifiers: [
|
||||
{
|
||||
name: "offset",
|
||||
options: {
|
||||
offset: [0, 10],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hide",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}, 1500);
|
||||
});
|
||||
|
||||
["mouseout", "click"].forEach((event) => {
|
||||
document.addEventListener(event, () => {
|
||||
isHovered = false;
|
||||
hideTooltip();
|
||||
});
|
||||
});
|
||||
},
|
||||
beforeUnmount(el: HTMLElement) {
|
||||
hideTooltip();
|
||||
|
||||
+22
-6
@@ -1,16 +1,32 @@
|
||||
<template>
|
||||
<div class="queue-view">
|
||||
<Queue :isOnQueuePage="true" />
|
||||
<SongList :tracks="queue.tracklist" @playFromPage="playFromQueuePage" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Queue from "@/components/RightSideBar/Queue.vue";
|
||||
import useQStore from "@/stores/queue";
|
||||
import { focusElem } from "@/utils";
|
||||
import SongList from "@/components/FolderView/SongList.vue";
|
||||
import { onMounted } from "vue";
|
||||
|
||||
const queue = useQStore();
|
||||
|
||||
function playFromQueuePage(index: number) {
|
||||
queue.play(index);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
focusElem("current");
|
||||
}, 1000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
<!-- <style lang="scss">
|
||||
.queue-view {
|
||||
background-color: $black;
|
||||
height: 100%;
|
||||
.table {
|
||||
margin-top: -1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style> -->
|
||||
|
||||
Reference in New Issue
Block a user