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:
geoffrey45
2022-09-06 18:53:26 +03:00
parent d114aa48cd
commit 6e46750270
11 changed files with 206 additions and 100 deletions
+1
View File
@@ -67,6 +67,7 @@ button {
justify-content: center; justify-content: center;
height: 2.25rem; height: 2.25rem;
background: linear-gradient(70deg, $gray3, $gray2); background: linear-gradient(70deg, $gray3, $gray2);
padding: 0 $small;
&:hover { &:hover {
background-image: linear-gradient(70deg, $darkestblue, $darkblue); background-image: linear-gradient(70deg, $darkestblue, $darkblue);
+2 -2
View File
@@ -1,6 +1,6 @@
<template> <template>
<div <div
class="table" class="table border rounded"
v-if="tracks.length" v-if="tracks.length"
ref="tracklistElem" ref="tracklistElem"
:class="{ :class="{
@@ -39,13 +39,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import { useElementSize } from "@vueuse/core"; import { useElementSize } from "@vueuse/core";
import { computed } from "@vue/reactivity";
import SongItem from "../shared/SongItem.vue"; import SongItem from "../shared/SongItem.vue";
import { Routes } from "@/composables/enums"; import { Routes } from "@/composables/enums";
import { Track } from "@/interfaces"; import { Track } from "@/interfaces";
import useQStore from "@/stores/queue"; import useQStore from "@/stores/queue";
import { computed } from "@vue/reactivity";
const queue = useQStore(); const queue = useQStore();
@@ -10,7 +10,6 @@
<span>Shuffle</span> <span>Shuffle</span>
</button> </button>
</div> </div>
<div class="right"></div>
</div> </div>
</template> </template>
@@ -37,20 +36,11 @@ const queue = useQueueStore();
} }
.action { .action {
padding: $smaller; padding-left: $smaller;
padding-right: $small;
svg { svg {
transform: scale(0.8); transform: scale(0.8);
} }
} }
.btn-more {
padding-right: $smaller;
svg {
transform: scale(1.25);
}
}
} }
</style> </style>
+15 -10
View File
@@ -13,9 +13,10 @@
<Folder v-if="$route.name == Routes.folder" :subPaths="subPaths" /> <Folder v-if="$route.name == Routes.folder" :subPaths="subPaths" />
<SearchTitle v-if="$route.name == Routes.search" /> <SearchTitle v-if="$route.name == Routes.search" />
<PlaylistsTitle v-if="$route.name == Routes.playlists" /> <PlaylistsTitle v-if="$route.name == Routes.playlists" />
<QueueTitle v-if="$route.name == Routes.queue" />
</div> </div>
</div> </div>
<!-- <!--
<div class="center rounded"> <div class="center rounded">
<Loader /> <Loader />
</div> --> </div> -->
@@ -23,21 +24,24 @@
</template> </template>
<script setup lang="ts"> <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 { ref, watch } from "vue";
import { Routes } from "@/composables/enums"; import { useRoute } from "vue-router";
import { createSubPaths } from "@/utils"; import { computed } from "@vue/reactivity";
import { subPath } from "@/interfaces"; 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 Folder from "./Titles/Folder.vue";
import SimpleTitle from "./Titles/SimpleTitle.vue"; import SimpleTitle from "./Titles/SimpleTitle.vue";
import APTitle from "./Titles/APTitle.vue"; import APTitle from "./Titles/APTitle.vue";
import useNavStore from "@/stores/nav";
import { computed } from "@vue/reactivity";
import SearchTitle from "./Titles/SearchTitle.vue"; import SearchTitle from "./Titles/SearchTitle.vue";
import PlaylistsTitle from "./Titles/PlaylistsTitle.vue"; import PlaylistsTitle from "./Titles/PlaylistsTitle.vue";
import QueueTitle from "./Titles/QueueTitle.vue";
const route = useRoute(); const route = useRoute();
const nav = useNavStore(); const nav = useNavStore();
@@ -53,7 +57,7 @@ const showAPTitle = computed(() => {
watch( watch(
() => route.name, () => route.name,
(newRoute: string) => { (newRoute) => {
switch (newRoute) { switch (newRoute) {
case Routes.folder: case Routes.folder:
let oldpath = ""; let oldpath = "";
@@ -90,6 +94,7 @@ watch(
display: grid; display: grid;
grid-template-columns: max-content 1fr; grid-template-columns: max-content 1fr;
gap: 1rem; gap: 1rem;
height: 2.25rem;
.info { .info {
margin: auto 0; margin: auto 0;
+7 -8
View File
@@ -20,18 +20,17 @@ import ArrowSvg from "../../assets/icons/right-arrow.svg";
gap: 1rem; gap: 1rem;
padding-right: 1.25rem; padding-right: 1.25rem;
border-right: 1px solid $gray3; border-right: 1px solid $gray3;
width: 100%; width: max-content;
height: 100%;
& > * { & > * {
width: 2.25rem;
background-color: $gray3; background-color: $gray3;
padding: $small;
height: 100%;
aspect-ratio: 1; aspect-ratio: 1;
border-radius: $medium; display: flex;
justify-content: center;
svg { align-items: center;
margin: auto; padding: 0;
}
} }
.back { .back {
+1 -2
View File
@@ -19,7 +19,7 @@ const things = computed(() => {
const route = useRoute(); const route = useRoute();
let thing = { let thing = {
text: "", text: "",
store: null, store: null as any,
source: playSources.album, source: playSources.album,
}; };
@@ -38,7 +38,6 @@ const things = computed(() => {
store: usePStore, store: usePStore,
}; };
break; break;
break;
} }
return thing; return thing;
+113
View File
@@ -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>
+1 -3
View File
@@ -24,9 +24,7 @@ defineProps<{
<style lang="scss"> <style lang="scss">
.play-btn { .play-btn {
height: 100%;
aspect-ratio: 1; aspect-ratio: 1;
display: grid; padding: 0;
place-items: center;
} }
</style> </style>
+6 -8
View File
@@ -76,7 +76,6 @@ const imguri = paths.images.thumb;
const options_button_clicked = ref(false); const options_button_clicked = ref(false);
const artisttitle = ref<HTMLElement | null>(null); const artisttitle = ref<HTMLElement | null>(null);
const tooltip = ref<HTMLElement | null>(null);
const props = defineProps<{ const props = defineProps<{
track: Track; track: Track;
@@ -107,13 +106,14 @@ function showMenu(e: Event) {
height: 3.75rem; height: 3.75rem;
gap: 1rem; gap: 1rem;
user-select: none; user-select: none;
// background-color: $gray;
// &:nth-child(odd) {
// background-color: rgba(26, 26, 26, 0.068);
// }
&:hover { &:hover {
background-color: $gray4; background-color: $gray4;
.options-icon {
opacity: 1 !important;
}
} }
.song-album { .song-album {
@@ -138,7 +138,6 @@ function showMenu(e: Event) {
opacity: 0.5; opacity: 0.5;
font-size: 0.8rem; font-size: 0.8rem;
width: 100%; width: 100%;
// margin-left: $small;
} }
.song-duration { .song-duration {
@@ -151,7 +150,6 @@ function showMenu(e: Event) {
} }
.options-icon { .options-icon {
opacity: 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -160,7 +158,7 @@ function showMenu(e: Event) {
svg { svg {
transition: all 0.2s ease-in; transition: all 0.2s ease-in;
transform: rotate(90deg); // transform: rotate(90deg);
stroke: $track-btn-svg; stroke: $track-btn-svg;
circle { circle {
+37 -50
View File
@@ -1,4 +1,4 @@
import { Directive, Ref, ref } from "vue"; import { Directive } from "vue";
import { createPopper } from "@popperjs/core"; import { createPopper } from "@popperjs/core";
let tooltip: HTMLElement; let tooltip: HTMLElement;
@@ -11,60 +11,47 @@ function hideTooltip() {
tooltip.style.visibility = "hidden"; 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 { export default {
mounted(el: HTMLElement, binding) { mounted(el, binding) {
let isHovered = false;
if (tooltip === undefined) { if (tooltip === undefined) {
tooltip = getTooltip(); tooltip = getTooltip();
} }
handleHover(el, binding.value); el.addEventListener("mouseover", () => {
}, isHovered = true;
updated(el, binding) {
el.removeEventListener("mouseover", () => {}); setTimeout(() => {
handleHover(el, binding.value, false); 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) { beforeUnmount(el: HTMLElement) {
hideTooltip(); hideTooltip();
+22 -6
View File
@@ -1,16 +1,32 @@
<template> <template>
<div class="queue-view"> <div class="queue-view">
<Queue :isOnQueuePage="true" /> <SongList :tracks="queue.tracklist" @playFromPage="playFromQueuePage" />
</div> </div>
</template> </template>
<script setup lang="ts"> <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> </script>
<style lang="scss"> <!-- <style lang="scss">
.queue-view { .queue-view {
background-color: $black; .table {
height: 100%; margin-top: -1rem;
}
} }
</style> </style> -->