link context menu to tracks

This commit is contained in:
geoffrey45 2022-03-14 08:46:21 +03:00
parent e8d2f31989
commit 658aba45ff
2 changed files with 92 additions and 38 deletions

View File

@ -1,86 +1,119 @@
<template> <template>
<div <div
class="songlist-item rounded" class="songlist-item rounded"
:class="{ current: current.trackid === song.trackid }" :class="[
@dblclick="emitUpdate(song)" { current: current.trackid === props.song.trackid },
{ 'context-on': context_on },
]"
@dblclick="emitUpdate(props.song)"
@contextmenu="showContextMenu"
> >
<div class="index">{{ index }}</div> <div class="index">{{ props.index }}</div>
<div class="flex"> <div class="flex">
<div <div
class="album-art image rounded" class="album-art image rounded"
:style="{ backgroundImage: `url(&quot;${song.image}&quot;` }" :style="{ backgroundImage: `url(&quot;${props.song.image}&quot;` }"
@click="emitUpdate(song)" @click="emitUpdate(props.song)"
> >
<div <div
class="now-playing-track image" class="now-playing-track image"
v-if="current.trackid === song.trackid" v-if="current.trackid === props.song.trackid"
:class="{ active: is_playing, not_active: !is_playing }" :class="{ active: is_playing, not_active: !is_playing }"
></div> ></div>
</div> </div>
<div @click="emitUpdate(song)"> <div @click="emitUpdate(props.song)">
<span class="ellip title">{{ song.title }}</span> <span class="ellip title">{{ props.song.title }}</span>
<div class="artist ellip"> <div class="artist ellip">
<span v-for="artist in putCommas(song.artists)" :key="artist"> <span
v-for="artist in perks.putCommas(props.song.artists)"
:key="artist"
>
{{ artist }} {{ artist }}
</span> </span>
</div> </div>
</div> </div>
</div> </div>
<div class="song-artists"> <div class="song-artists">
<div class="ellip" v-if="song.artists[0] !== ''"> <div class="ellip" v-if="props.song.artists[0] !== ''">
<span <span
class="artist" class="artist"
v-for="artist in putCommas(song.artists)" v-for="artist in perks.putCommas(props.song.artists)"
:key="artist" :key="artist"
>{{ artist }}</span >{{ artist }}</span
> >
</div> </div>
<div class="ellip" v-else> <div class="ellip" v-else>
<span class="artist">{{ song.albumartist }}</span> <span class="artist">{{ props.song.albumartist }}</span>
</div> </div>
</div> </div>
<div class="song-album"> <div class="song-album">
<div <div
class="album ellip" class="album ellip"
@click="emitLoadAlbum(song.album, song.albumartist)" @click="emitLoadAlbum(props.song.album, props.song.albumartist)"
> >
{{ song.album }} {{ props.song.album }}
</div> </div>
</div> </div>
<div class="song-duration">{{ formatSeconds(song.length) }}</div> <div class="song-duration">
<ContextMenu /> {{ perks.formatSeconds(props.song.length) }}
</div>
</div> </div>
</template> </template>
<script> <script setup>
import perks from "@/composables/perks.js"; import perks from "@/composables/perks.js";
import state from "@/composables/state.js"; import state from "@/composables/state.js";
import ContextMenu from "../contextMenu.vue"; import useContextStore from "../../stores/context.js";
import { ref } from "vue";
import trackContext from "../../composables/track_context";
export default { const contextStore = useContextStore();
props: ["song", "index"], const context_on = ref(false);
emits: ["updateQueue", "loadAlbum"],
setup(props, { emit }) { const showContextMenu = (e) => {
function emitUpdate(song) { e.preventDefault();
emit("updateQueue", song); e.stopPropagation();
contextStore.showContextMenu(e, trackContext(props.song));
context_on.value = true;
contextStore.$subscribe((mutation, state) => {
if (!state.visible) {
context_on.value = false;
} }
function emitLoadAlbum(title, artist) { });
emit("loadAlbum", title, artist);
}
return {
putCommas: perks.putCommas,
emitUpdate,
emitLoadAlbum,
is_playing: state.is_playing,
current: state.current,
formatSeconds: perks.formatSeconds,
};
},
components: { ContextMenu },
}; };
const props = defineProps({
song: {
type: Object,
default: () => ({}),
},
index: {
type: Number,
default: () => 0,
},
});
const emit = defineEmits(["updateQeuue", "loadAlbum"]);
function emitUpdate(song) {
emit("updateQueue", song);
}
function emitLoadAlbum(title, artist) {
emit("loadAlbum", title, artist);
}
const is_playing = state.is_playing;
const current = state.current;
</script> </script>
<style lang="scss"> <style lang="scss">
.context-on {
background-color: $gray4;
color: $white !important;
}
.songlist-item { .songlist-item {
display: grid; display: grid;
align-items: center; align-items: center;
@ -89,6 +122,14 @@ export default {
text-align: left; text-align: left;
gap: $small; gap: $small;
.context {
position: fixed;
top: 0;
left: 0;
height: 45px;
width: 45px;
background-color: red;
}
@include tablet-landscape { @include tablet-landscape {
grid-template-columns: 1.5rem 1.5fr 1fr 1.5fr; grid-template-columns: 1.5rem 1.5fr 1fr 1.5fr;
} }
@ -98,7 +139,7 @@ export default {
} }
&:hover { &:hover {
background-color: $gray; background-color: $gray4;
} }
.song-duration { .song-duration {

View File

@ -5,6 +5,7 @@
:class="{ :class="{
currentInQueue: current.trackid === props.track.trackid, currentInQueue: current.trackid === props.track.trackid,
}" }"
@contextmenu="showContextMenu"
> >
<div <div
class="album-art image rounded" class="album-art image rounded"
@ -34,9 +35,20 @@
import { ref } from "vue"; import { ref } from "vue";
import perks from "../../composables/perks"; import perks from "../../composables/perks";
import playAudio from "../../composables/playAudio"; import playAudio from "../../composables/playAudio";
import useContextStore from "@/stores/context.js";
import trackContext from "../../composables/track_context";
const contextStore = useContextStore();
const showContextMenu = (e) => {
e.preventDefault();
e.stopPropagation();
contextStore.showContextMenu(e, trackContext(props.track));
};
const props = defineProps({ const props = defineProps({
track: Object, track: Object,
default: () => ({}),
}); });
const current = ref(perks.current); const current = ref(perks.current);
@ -55,6 +67,7 @@ const playThis = (song) => {
} }
.track-item { .track-item {
width: 26.55rem;
display: flex; display: flex;
align-items: center; align-items: center;
border-radius: 0.5rem; border-radius: 0.5rem;