mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-06-06 19:25:34 +00:00
225 lines
4.5 KiB
Vue
225 lines
4.5 KiB
Vue
<template>
|
|
<div
|
|
class="songlist-item rounded"
|
|
:class="[{ current: props.isCurrent }, { 'context-on': context_on }]"
|
|
@dblclick="emitUpdate(props.song)"
|
|
@contextmenu="showContextMenu"
|
|
>
|
|
<div class="index">{{ props.index }}</div>
|
|
<div class="flex">
|
|
<div
|
|
class="album-art image rounded"
|
|
:style="{
|
|
backgroundImage: `url("${
|
|
imguri + props.song.image
|
|
}"`,
|
|
}"
|
|
@click="emitUpdate(props.song)"
|
|
>
|
|
<div
|
|
class="now-playing-track image"
|
|
v-if="props.isPlaying && props.isCurrent"
|
|
:class="{ active: isPlaying, not_active: !isPlaying }"
|
|
></div>
|
|
</div>
|
|
<div @click="emitUpdate(props.song)">
|
|
<span class="ellip title">{{ props.song.title }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="song-artists">
|
|
<div class="ellip" v-if="props.song.artists[0] !== ''">
|
|
<span
|
|
class="artist"
|
|
v-for="artist in perks.putCommas(props.song.artists)"
|
|
:key="artist"
|
|
>{{ artist }}</span
|
|
>
|
|
</div>
|
|
<div class="ellip" v-else>
|
|
<span class="artist">{{ props.song.albumartist }}</span>
|
|
</div>
|
|
</div>
|
|
<router-link
|
|
class="song-album"
|
|
:to="{
|
|
name: 'AlbumView',
|
|
params: {
|
|
album: props.song.album,
|
|
artist: props.song.albumartist,
|
|
},
|
|
}"
|
|
>
|
|
<div class="album ellip">
|
|
{{ props.song.album }}
|
|
</div>
|
|
</router-link>
|
|
<div class="song-duration">
|
|
{{ perks.formatSeconds(props.song.length) }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import perks from "../../composables/perks.js";
|
|
import useContextStore from "../../stores/context";
|
|
import useModalStore from "../../stores/modal";
|
|
import useQueueStore from "../../stores/queue";
|
|
import { ContextSrc } from "../../composables/enums";
|
|
|
|
import { ref } from "vue";
|
|
import trackContext from "../../contexts/track_context";
|
|
import { Track } from "../../interfaces.js";
|
|
import { paths } from "../../config";
|
|
|
|
const contextStore = useContextStore();
|
|
|
|
const context_on = ref(false);
|
|
const imguri = paths.images.thumb
|
|
|
|
const showContextMenu = (e: Event) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
const menus = trackContext(props.song, useModalStore, useQueueStore);
|
|
|
|
contextStore.showContextMenu(e, menus, ContextSrc.Track);
|
|
context_on.value = true;
|
|
|
|
contextStore.$subscribe((mutation, state) => {
|
|
if (!state.visible) {
|
|
context_on.value = false;
|
|
}
|
|
});
|
|
};
|
|
|
|
const props = defineProps<{
|
|
song: Track;
|
|
index: Number;
|
|
isPlaying: Boolean;
|
|
isCurrent: Boolean;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
(e: "updateQueue", song: Track): void;
|
|
}>();
|
|
|
|
function emitUpdate(track: Track) {
|
|
emit("updateQueue", track);
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.songlist-item {
|
|
display: grid;
|
|
align-items: center;
|
|
grid-template-columns: 1.5rem 1.5fr 1fr 1.5fr 0.25fr;
|
|
height: 3.75rem;
|
|
text-align: left;
|
|
gap: $small;
|
|
user-select: none;
|
|
-moz-user-select: none;
|
|
|
|
.context {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
height: 45px;
|
|
width: 45px;
|
|
background-color: red;
|
|
}
|
|
|
|
@include tablet-landscape {
|
|
grid-template-columns: 1.5rem 1.5fr 1fr 1.5fr;
|
|
}
|
|
|
|
@include tablet-portrait {
|
|
grid-template-columns: 1.5rem 1.5fr 1fr;
|
|
}
|
|
|
|
&:hover {
|
|
background-color: $gray4;
|
|
}
|
|
|
|
.song-duration {
|
|
@include tablet-landscape {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.song-album {
|
|
.album {
|
|
cursor: pointer;
|
|
max-width: max-content;
|
|
}
|
|
|
|
@include tablet-portrait {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.song-artists {
|
|
.artist {
|
|
cursor: pointer;
|
|
}
|
|
|
|
@include phone-only {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.index {
|
|
color: grey;
|
|
font-size: 0.8rem;
|
|
text-align: center;
|
|
width: 2rem;
|
|
|
|
@include phone-only {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.song-duration {
|
|
font-size: 0.9rem;
|
|
width: 5rem !important;
|
|
}
|
|
|
|
.flex {
|
|
position: relative;
|
|
padding-left: 4rem;
|
|
align-items: center;
|
|
|
|
.album-art {
|
|
position: absolute;
|
|
left: $small;
|
|
width: 3rem;
|
|
height: 3rem;
|
|
margin-right: 1rem;
|
|
display: grid;
|
|
place-items: center;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.title {
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
td {
|
|
height: 4rem;
|
|
padding: $small;
|
|
}
|
|
|
|
td:first-child {
|
|
border-radius: $small 0 0 $small;
|
|
}
|
|
|
|
td:nth-child(2) {
|
|
border-radius: 0 $small $small 0;
|
|
|
|
@include phone-only {
|
|
border-radius: $small;
|
|
}
|
|
}
|
|
}
|
|
</style>
|