mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 12:33:03 +00:00
responsiveness improvements
+ extract track context menu handler into a composable
This commit is contained in:
@@ -44,14 +44,14 @@ defineProps<{
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: $small;
|
||||
min-height: 15rem;
|
||||
}
|
||||
|
||||
@include tablet-portrait {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
@include for-desktop-down {
|
||||
grid-template-columns: 1fr !important;
|
||||
|
||||
@include tablet-landscape {
|
||||
grid-template-columns: 1fr auto;
|
||||
.left {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
@@ -60,16 +60,12 @@ defineProps<{
|
||||
width: 100%;
|
||||
margin-right: $small;
|
||||
overflow: hidden;
|
||||
bg-black: solid 1px $gray5;
|
||||
border: solid 1px $gray5;
|
||||
background-image: linear-gradient(37deg, $gray5 20%, $gray4);
|
||||
|
||||
@include tablet-portrait {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@include tablet-landscape {
|
||||
width: 10rem;
|
||||
}
|
||||
// @include for-desktop-down {
|
||||
// display: none;
|
||||
// }
|
||||
|
||||
$rectpos: calc(50% - 5rem);
|
||||
|
||||
@@ -95,7 +91,7 @@ defineProps<{
|
||||
height: 7rem;
|
||||
bottom: 0;
|
||||
left: calc($rectpos + 7rem);
|
||||
bg-black-radius: 50%;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 2rem rgb(0, 0, 0);
|
||||
transition: all 0.25s ease-in-out;
|
||||
|
||||
@@ -105,7 +101,7 @@ defineProps<{
|
||||
}
|
||||
}
|
||||
.bio {
|
||||
bg-black: solid 1px $gray5;
|
||||
border: solid 1px $gray5;
|
||||
padding: $small;
|
||||
line-height: 1.5rem;
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ const emit = defineEmits<{
|
||||
(event: "resetBottomPadding"): void;
|
||||
}>();
|
||||
|
||||
const albumheaderthing = ref<HTMLElement>(null);
|
||||
const albumheaderthing = ref<any>(null);
|
||||
const imguri = paths.images.thumb;
|
||||
const nav = useNavStore();
|
||||
|
||||
@@ -121,6 +121,9 @@ useVisibility(albumheaderthing, handleVisibilityState);
|
||||
justify-content: flex-end;
|
||||
|
||||
.top {
|
||||
.h {
|
||||
opacity: 0.75;
|
||||
}
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 600;
|
||||
@@ -146,5 +149,18 @@ useVisibility(albumheaderthing, handleVisibilityState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include for-desktop-down {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
.art > img {
|
||||
height: 6rem;
|
||||
box-shadow: 0 0 1rem $black;
|
||||
}
|
||||
|
||||
.info > .top > .title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -24,7 +24,5 @@ defineProps<{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
|
||||
gap: $medium;
|
||||
padding: $small;
|
||||
background-color: $gray5;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
<template>
|
||||
<div class="folder">
|
||||
<div class="table rounded" v-if="tracks.length">
|
||||
<div class="header" v-if="disc && !album.info.is_single">
|
||||
<div class="disc-number">Disc {{ disc }}</div>
|
||||
<div class="header">
|
||||
<div class="disc-number" v-if="disc">Disc {{ disc }}</div>
|
||||
<div class="disc-number" v-if="$route.name === Routes.folder">
|
||||
In this folder
|
||||
</div>
|
||||
<div class="disc-number" v-if="$route.name === Routes.playlist">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="songlist">
|
||||
<SongItem
|
||||
@@ -13,7 +19,7 @@
|
||||
@updateQueue="updateQueue"
|
||||
:isPlaying="queue.playing"
|
||||
:isCurrent="queue.currentid == track.trackid"
|
||||
:isHighlighted="highlightid == track.uniq_hash"
|
||||
:isHighlighted="($route.query.highlight as string) == track.uniq_hash"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,6 +44,7 @@ import { onMounted, onUpdated, ref } from "vue";
|
||||
import { Track } from "@/interfaces";
|
||||
import useQStore from "@/stores/queue";
|
||||
import useAlbumStore from "@/stores/pages/album";
|
||||
import { Routes } from "@/composables/enums";
|
||||
|
||||
const queue = useQStore();
|
||||
const album = useAlbumStore();
|
||||
@@ -54,12 +61,18 @@ const props = defineProps<{
|
||||
|
||||
const route = useRoute();
|
||||
const routename = route.name as string;
|
||||
const highlightid = ref(route.query.highlight as string);
|
||||
const highlightid = ref(route.query.highlight as string | null);
|
||||
|
||||
function highlightTrack(t_hash: string) {
|
||||
focusElem(`track-${t_hash}`, 500, "center");
|
||||
}
|
||||
|
||||
function resetHighlight() {
|
||||
setTimeout(() => {
|
||||
highlightid.value = null;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
onBeforeRouteUpdate(async (to, from) => {
|
||||
const h_hash = to.query.highlight as string;
|
||||
highlightid.value = h_hash as string;
|
||||
@@ -72,12 +85,14 @@ onBeforeRouteUpdate(async (to, from) => {
|
||||
onUpdated(() => {
|
||||
if (highlightid.value) {
|
||||
highlightTrack(highlightid.value);
|
||||
resetHighlight();
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (highlightid.value) {
|
||||
highlightTrack(highlightid.value);
|
||||
resetHighlight();
|
||||
}
|
||||
});
|
||||
/**
|
||||
@@ -187,6 +202,7 @@ function getTrackList() {
|
||||
|
||||
.songlist {
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="r-home">
|
||||
<UpNext :next="queue.tracklist[queue.next]" :playNext="queue.playNext" />
|
||||
<Recommendations />
|
||||
<UpNext :track="queue.tracklist[queue.next]" :playNext="queue.playNext" />
|
||||
<!-- <Recommendations /> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
</style>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Recommendations from "./Recommendation.vue";
|
||||
import UpNext from "../Queue/upNext.vue";
|
||||
import useQStore from "../../../stores/queue";
|
||||
import UpNext from "../Queue/upNext.vue";
|
||||
const queue = useQStore();
|
||||
</script>
|
||||
|
||||
@@ -29,14 +29,6 @@ const tabs = useTabStore();
|
||||
.r-sidebar {
|
||||
width: 100%;
|
||||
|
||||
@include phone-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@include tablet-landscape {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
position: relative;
|
||||
@@ -44,12 +36,8 @@ const tabs = useTabStore();
|
||||
|
||||
.r-content {
|
||||
grid-area: content;
|
||||
width: 29rem;
|
||||
// width: 100%;
|
||||
|
||||
// @include tablet-landscape {
|
||||
// display: none;
|
||||
// }
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
.r-search {
|
||||
height: 100%;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<div class="up-next">
|
||||
<div class="r-grid">
|
||||
<UpNext :next="queue.tracklist[queue.next]" :playNext="queue.playNext" />
|
||||
<UpNext :track="queue.tracklist[queue.next]" :playNext="queue.playNext" />
|
||||
<div class="scrollable-r bg-black rounded">
|
||||
<QueueActions />
|
||||
<div class="inner">
|
||||
<TransitionGroup
|
||||
name="queuelist"
|
||||
@mouseenter="setMouseOver(true)"
|
||||
@mouseleave="setMouseOver(false)"
|
||||
>
|
||||
<div
|
||||
class="inner"
|
||||
@mouseenter="setMouseOver(true)"
|
||||
@mouseleave="setMouseOver(false)"
|
||||
>
|
||||
<TransitionGroup name="queuelist">
|
||||
<TrackItem
|
||||
v-for="(t, index) in queue.tracklist"
|
||||
:key="t.trackid"
|
||||
:key="index"
|
||||
:track="t"
|
||||
@playThis="queue.play(index)"
|
||||
:isCurrent="index === queue.current"
|
||||
@@ -29,13 +29,13 @@
|
||||
<script setup lang="ts">
|
||||
import { onUpdated, ref } from "vue";
|
||||
|
||||
import { focusElem } from "@/utils";
|
||||
import useQStore from "@/stores/queue";
|
||||
import { focusElem } from "@/utils";
|
||||
|
||||
import UpNext from "./Queue/upNext.vue";
|
||||
import TrackItem from "../shared/TrackItem.vue";
|
||||
import PlayingFrom from "./Queue/playingFrom.vue";
|
||||
import QueueActions from "./Queue/QueueActions.vue";
|
||||
import UpNext from "./Queue/upNext.vue";
|
||||
|
||||
const queue = useQStore();
|
||||
const mouseover = ref(false);
|
||||
@@ -84,13 +84,10 @@ onUpdated(() => {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: max-content 1fr max-content;
|
||||
gap: $small;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
gap: $small;
|
||||
}
|
||||
|
||||
.scrollable-r {
|
||||
height: 100%;
|
||||
|
||||
@@ -36,6 +36,11 @@ const queue = useQueueStore();
|
||||
margin: 1rem;
|
||||
margin-bottom: 0;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
gap: $small;
|
||||
}
|
||||
|
||||
.action {
|
||||
padding: $smaller;
|
||||
padding-right: $small;
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
<template>
|
||||
<div class="main-item bg-black" @click="playNext">
|
||||
<div class="h">Up Next</div>
|
||||
<div class="itemx shadow">
|
||||
<div
|
||||
class="album-art image"
|
||||
:style="{
|
||||
backgroundImage: `url("${imguri + next.image}")`,
|
||||
}"
|
||||
></div>
|
||||
<div class="tags">
|
||||
<p class="title ellip">{{ next.title }}</p>
|
||||
<hr />
|
||||
<p class="artist ellip">
|
||||
<span v-for="artist in putCommas(next.artists)" :key="artist">{{
|
||||
artist
|
||||
}}</span>
|
||||
</p>
|
||||
<div
|
||||
class="next-track bg-black"
|
||||
:class="{ contexton: context_on }"
|
||||
@click="playNext"
|
||||
@contextmenu.prevent="showMenu"
|
||||
>
|
||||
<div class="nextup abs">next up</div>
|
||||
<img :src="paths.images.thumb + track.image" class="rounded" />
|
||||
<div class="tags">
|
||||
<div class="title ellip">{{ track.title }}</div>
|
||||
<div class="artist ellip">
|
||||
<span v-for="artist in putCommas(track.artists)" :key="artist">{{
|
||||
artist
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -23,67 +20,68 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { paths } from "@/config";
|
||||
import { putCommas } from "@/utils";
|
||||
import { Track } from "@/interfaces";
|
||||
import { putCommas } from "@/utils";
|
||||
|
||||
const imguri = paths.images.thumb;
|
||||
defineProps<{
|
||||
next: Track;
|
||||
import { showTrackContextMenu as showContext } from "@/composables/context";
|
||||
import { ref } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
track: Track;
|
||||
playNext: () => void;
|
||||
}>();
|
||||
|
||||
const context_on = ref(false);
|
||||
|
||||
function showMenu(e: Event) {
|
||||
showContext(e, props.track, context_on);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.main-item {
|
||||
.next-track {
|
||||
border-radius: 0.5rem;
|
||||
position: relative;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: max-content 1fr;
|
||||
gap: 1rem;
|
||||
padding: $small;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: $accent;
|
||||
background-color: $gray4;
|
||||
|
||||
.h {
|
||||
background-color: $black;
|
||||
}
|
||||
}
|
||||
|
||||
.h {
|
||||
position: absolute;
|
||||
.nextup {
|
||||
right: $small;
|
||||
bottom: $small;
|
||||
font-size: 0.9rem;
|
||||
background-color: $accent;
|
||||
top: 0;
|
||||
font-size: 0.8rem;
|
||||
padding: $smaller;
|
||||
border-radius: 0.25rem;
|
||||
font-style: oblique;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.itemx {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.album-art {
|
||||
img {
|
||||
width: 4.5rem;
|
||||
height: 4.5rem;
|
||||
background-image: url(../../assets/images/null.webp);
|
||||
margin: 0 0.5rem 0 0;
|
||||
border-radius: 0.5rem;
|
||||
aspect-ratio: 1;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.tags {
|
||||
hr {
|
||||
border: none;
|
||||
margin: 0.3rem;
|
||||
}
|
||||
.title {
|
||||
width: 20rem;
|
||||
margin: 0;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
gap: $small;
|
||||
|
||||
.artist {
|
||||
width: 20rem;
|
||||
margin: 0;
|
||||
font-size: small;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import TracksGrid from "./TracksGrid.vue";
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.heading {
|
||||
padding: $medium;
|
||||
|
||||
@@ -16,17 +16,22 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { onMounted } from "vue";
|
||||
import useSearchStore from "../../stores/search";
|
||||
|
||||
const search = useSearchStore();
|
||||
let input: HTMLInputElement;
|
||||
|
||||
onMounted(() => {
|
||||
input = document.getElementById("ginner") as HTMLInputElement;
|
||||
});
|
||||
|
||||
function focusThis() {
|
||||
document.getElementById("ginner").classList.add("focused");
|
||||
input.classList.add("focused");
|
||||
}
|
||||
|
||||
function unfocusThis() {
|
||||
document.getElementById("ginner").classList.remove("focused");
|
||||
input.classList.remove("focused");
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -34,11 +39,6 @@ function unfocusThis() {
|
||||
#gsearch-input {
|
||||
display: flex;
|
||||
height: max-content;
|
||||
// margin-bottom: $smaller;
|
||||
|
||||
@include tablet-landscape {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#ginner {
|
||||
width: 100%;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
v-for="option in context.options"
|
||||
:key="option.label"
|
||||
:class="[{ critical: option.critical }, option.type]"
|
||||
@click="option.action()"
|
||||
@click="() => option.action && option.action()"
|
||||
>
|
||||
<div class="icon image" :class="option.icon"></div>
|
||||
<div class="label ellip">{{ option.label }}</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
v-for="child in option.children"
|
||||
:key="child.label"
|
||||
:class="[{ critical: child.critical }, child.type]"
|
||||
@click="child.action()"
|
||||
@click="child.action && child.action()"
|
||||
>
|
||||
<div class="label ellip">
|
||||
{{ child.label }}
|
||||
@@ -69,14 +69,14 @@ const context = useContextStore();
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: default;
|
||||
padding: $small;
|
||||
padding: $small 1rem;
|
||||
position: relative;
|
||||
|
||||
.more {
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
right: $small;
|
||||
background-image: url("../assets/icons/expand.svg");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
]"
|
||||
v-bind:class="`track-${track.uniq_hash}`"
|
||||
@dblclick="emitUpdate(track)"
|
||||
@contextmenu="showContextMenu"
|
||||
@contextmenu.prevent="showMenu"
|
||||
>
|
||||
<div class="index t-center">{{ index }}</div>
|
||||
<div class="index t-center ellip">{{ index }}</div>
|
||||
<div class="flex">
|
||||
<div @click="emitUpdate(track)" class="thumbnail">
|
||||
<img
|
||||
@@ -58,17 +58,12 @@
|
||||
{{ track.album }}
|
||||
</router-link>
|
||||
<div class="song-duration">
|
||||
<div class="text">{{ formatSeconds(track.length) }}</div>
|
||||
<div class="text ellip">{{ formatSeconds(track.length) }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="options-icon circular"
|
||||
:class="{ options_button_clicked }"
|
||||
@click="
|
||||
(e) => {
|
||||
showContextMenu(e);
|
||||
options_button_clicked = true;
|
||||
}
|
||||
"
|
||||
@click.stop="showMenu"
|
||||
>
|
||||
<OptionSvg />
|
||||
</div>
|
||||
@@ -78,40 +73,17 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
import useModalStore from "@/stores/modal";
|
||||
import useQueueStore from "@/stores/queue";
|
||||
import useContextStore from "@/stores/context";
|
||||
import trackContext from "@/contexts/track_context";
|
||||
import OptionSvg from "@/assets/icons/more.svg";
|
||||
|
||||
import { paths } from "@/config";
|
||||
import { Track } from "@/interfaces";
|
||||
import { ContextSrc } from "@/composables/enums";
|
||||
import { formatSeconds, putCommas } from "@/utils";
|
||||
|
||||
const contextStore = useContextStore();
|
||||
import { showTrackContextMenu as showContext } from "@/composables/context";
|
||||
|
||||
const context_on = ref(false);
|
||||
const imguri = paths.images.thumb;
|
||||
const options_button_clicked = ref(false);
|
||||
|
||||
const showContextMenu = (e: Event) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const menus = trackContext(props.track, useModalStore, useQueueStore);
|
||||
|
||||
contextStore.showContextMenu(e, menus, ContextSrc.Track);
|
||||
context_on.value = true;
|
||||
|
||||
contextStore.$subscribe((mutation, state) => {
|
||||
if (!state.visible) {
|
||||
context_on.value = false;
|
||||
options_button_clicked.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const props = defineProps<{
|
||||
track: Track;
|
||||
index?: number;
|
||||
@@ -127,20 +99,32 @@ const emit = defineEmits<{
|
||||
function emitUpdate(track: Track) {
|
||||
emit("updateQueue", track);
|
||||
}
|
||||
|
||||
function showMenu(e: Event) {
|
||||
showContext(e, props.track, options_button_clicked);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.songlist-item {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-template-columns: 1.5rem 1.5fr 1fr 1.5fr 2rem 2.5rem;
|
||||
align-items: center;
|
||||
justify-items: flex-start;
|
||||
height: 3.75rem;
|
||||
text-align: left;
|
||||
gap: $small;
|
||||
gap: 1rem;
|
||||
user-select: none;
|
||||
|
||||
@include tablet-landscape {
|
||||
grid-template-columns: 1.5rem 1.5fr 1fr 1fr 2.5rem;
|
||||
@include for-desktop-down {
|
||||
grid-template-columns: 1.5rem 1.5fr 1fr 2.5rem;
|
||||
|
||||
.song-album {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.song-duration {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@include tablet-portrait {
|
||||
@@ -155,12 +139,6 @@ function emitUpdate(track: Track) {
|
||||
}
|
||||
}
|
||||
|
||||
.song-duration {
|
||||
@include tablet-landscape {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.song-album {
|
||||
word-break: break-all;
|
||||
max-width: max-content;
|
||||
@@ -169,10 +147,6 @@ function emitUpdate(track: Track) {
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@include tablet-portrait {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.song-artists {
|
||||
@@ -181,26 +155,17 @@ function emitUpdate(track: Track) {
|
||||
.artist {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@include phone-only {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.index {
|
||||
color: grey;
|
||||
opacity: 0.5;
|
||||
font-size: 0.8rem;
|
||||
width: 2rem;
|
||||
|
||||
@include phone-only {
|
||||
display: none;
|
||||
}
|
||||
width: 100%;
|
||||
margin-left: $small;
|
||||
}
|
||||
|
||||
.song-duration {
|
||||
font-size: 0.9rem;
|
||||
width: 5rem !important;
|
||||
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -211,7 +176,6 @@ function emitUpdate(track: Track) {
|
||||
justify-content: center;
|
||||
aspect-ratio: 1;
|
||||
width: 2rem;
|
||||
margin-right: 1rem;
|
||||
|
||||
svg {
|
||||
transition: all 0.2s ease-in;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
{ contexton: context_on },
|
||||
]"
|
||||
@contextmenu="showContextMenu"
|
||||
@contextmenu.prevent="showMenu"
|
||||
>
|
||||
<div class="album-art">
|
||||
<img :src="paths.images.thumb + track.image" alt="" class="rounded" />
|
||||
@@ -35,18 +35,10 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
import useModalStore from "@/stores/modal";
|
||||
import useQueueStore from "@/stores/queue";
|
||||
import useContextStore from "@/stores/context";
|
||||
import trackContext from "@/contexts/track_context";
|
||||
|
||||
import { paths } from "@/config";
|
||||
import { putCommas } from "@/utils";
|
||||
import { Track } from "@/interfaces";
|
||||
import { ContextSrc } from "@/composables/enums";
|
||||
|
||||
const contextStore = useContextStore();
|
||||
const imguri = paths.images.thumb;
|
||||
import { showTrackContextMenu as showContext } from "@/composables/context";
|
||||
|
||||
const props = defineProps<{
|
||||
track: Track;
|
||||
@@ -56,21 +48,9 @@ const props = defineProps<{
|
||||
|
||||
const context_on = ref(false);
|
||||
|
||||
const showContextMenu = (e: Event) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const menus = trackContext(props.track, useModalStore, useQueueStore);
|
||||
|
||||
contextStore.showContextMenu(e, menus, ContextSrc.Track);
|
||||
context_on.value = true;
|
||||
|
||||
contextStore.$subscribe((mutation, state) => {
|
||||
if (!state.visible) {
|
||||
context_on.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
function showMenu(e: Event) {
|
||||
showContext(e, props.track, context_on);
|
||||
}
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "PlayThis"): void;
|
||||
|
||||
Reference in New Issue
Block a user