mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 12:33:03 +00:00
🔷 add PlayingFrom component to right sidebar
🔷 move upNext card into separate component 🔷 a lot of refactors
This commit is contained in:
@@ -4,47 +4,38 @@
|
||||
<div
|
||||
class="image art shadow-lg rounded"
|
||||
:style="{
|
||||
backgroundImage: `url("${props.album_info.image}")`,
|
||||
backgroundImage: `url("${props.album.image}")`,
|
||||
}"
|
||||
></div>
|
||||
<div class="info">
|
||||
<div class="top">
|
||||
<div class="h">Album</div>
|
||||
<div class="separator no-border"></div>
|
||||
<div class="title">{{ props.album_info.album }}</div>
|
||||
<div class="artist">{{ props.album_info.artist }}</div>
|
||||
<div class="title">{{ props.album.album }}</div>
|
||||
<div class="artist">{{ props.album.artist }}</div>
|
||||
</div>
|
||||
<div class="separator no-border"></div>
|
||||
<div class="bottom">
|
||||
<div class="stats shadow-sm">
|
||||
{{ props.album_info.count }} Tracks •
|
||||
{{ perks.formatSeconds(props.album_info.duration, "long") }} •
|
||||
{{ props.album_info.date }}
|
||||
</div>
|
||||
<div class="play rounded" @click="playAlbum">
|
||||
<div class="icon"></div>
|
||||
<div>Play</div>
|
||||
{{ props.album.count }} Tracks •
|
||||
{{ perks.formatSeconds(props.album.duration, "long") }} •
|
||||
{{ props.album.date }}
|
||||
</div>
|
||||
<PlayBtnRect :source="playSources.album" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import state from "@/composables/state";
|
||||
import perks from "@/composables/perks.js";
|
||||
|
||||
const props = defineProps({
|
||||
album_info: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
function playAlbum() {
|
||||
perks.updateQueue(state.album.tracklist[0], "album");
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import perks from "../../composables/perks.js";
|
||||
import { AlbumInfo } from "../../interfaces.js";
|
||||
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
||||
import { playSources } from "../../composables/enums";
|
||||
const props = defineProps<{
|
||||
album: AlbumInfo;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
v-for="artist in artists"
|
||||
:key="artist"
|
||||
:artist="artist"
|
||||
:color="ffffff00"
|
||||
:color="'ffffff00'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="p-header">
|
||||
<div class="carddd">
|
||||
<div class="art image"></div>
|
||||
<div class="art image shadow-sm"></div>
|
||||
<div class="info">
|
||||
<div class="btns">
|
||||
<PlayBtnRect :source="playSources.playlist" />
|
||||
</div>
|
||||
<div class="duration">4 Tracks • 3 Hours</div>
|
||||
<div class="duration">{{props.info.count}} Tracks • 3 Hours</div>
|
||||
<div class="desc">
|
||||
{{ props.info.desc[0] }}
|
||||
{{ props.info.description }}
|
||||
</div>
|
||||
<div class="title ellip">{{ props.info.name }}</div>
|
||||
<div class="type">Playlist</div>
|
||||
@@ -25,16 +25,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { playSources } from "../../composables/enums";
|
||||
import { Playlist } from "../../interfaces";
|
||||
|
||||
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
||||
const props = defineProps<{
|
||||
info: {
|
||||
name: string;
|
||||
count: number;
|
||||
duration: string;
|
||||
desc: string;
|
||||
lastUpdated: string;
|
||||
};
|
||||
info: Playlist;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
@@ -43,9 +38,7 @@ const props = defineProps<{
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
height: 14rem;
|
||||
// background-image: url("../../assets/images/eggs.jpg");
|
||||
|
||||
background-image: linear-gradient(23deg, $black 40%, rgb(141, 11, 2), $black);
|
||||
background-image: linear-gradient(37deg, $black 4%, $accent, $black);
|
||||
position: relative;
|
||||
margin-top: $small;
|
||||
border-radius: 0.75rem;
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
<template>
|
||||
<div class="r-home">
|
||||
<Recommendations />
|
||||
<UpNext :next="queue.next" :playNext="queue.playNext" />
|
||||
<Recommendations />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.r-home {
|
||||
height: calc(100% - 1rem);
|
||||
// padding: 0 $small $small 0;
|
||||
padding: 0 $small $small 0;
|
||||
margin-top: $small;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script setup>
|
||||
import Recommendations from '../Recommendation.vue';
|
||||
</script>
|
||||
<script setup lang="ts">
|
||||
import Recommendations from "../Recommendation.vue";
|
||||
import UpNext from "../queue/upNext.vue";
|
||||
import useQStore from "../../../stores/queue";
|
||||
const queue = useQStore();
|
||||
</script>
|
||||
|
||||
@@ -1,28 +1,8 @@
|
||||
<template>
|
||||
<div class="up-next">
|
||||
<div class="r-grid">
|
||||
<div class="main-item border">
|
||||
<p class="heading">COMING UP NEXT</p>
|
||||
<div class="itemx" @click="queue.playNext">
|
||||
<div
|
||||
class="album-art image"
|
||||
:style="{
|
||||
backgroundImage: `url("${queue.next.image}")`,
|
||||
}"
|
||||
></div>
|
||||
<div class="tags">
|
||||
<p class="title ellip">{{ queue.next.title }}</p>
|
||||
<hr />
|
||||
<p class="artist ellip">
|
||||
<span
|
||||
v-for="artist in putCommas(queue.next.artists)"
|
||||
:key="artist"
|
||||
>{{ artist }}</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<PlayingFrom :from="queue.from" />
|
||||
<UpNext :next="queue.next" :playNext="queue.playNext" />
|
||||
<div class="scrollable-r border rounded">
|
||||
<TrackItem
|
||||
v-for="t in queue.tracks"
|
||||
@@ -38,16 +18,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import perks from "../../composables/perks.js";
|
||||
import TrackItem from "../shared/TrackItem.vue";
|
||||
import useQStore from "../../stores/queue";
|
||||
import { Track } from "../../interfaces.js";
|
||||
import { onBeforeMount } from "vue";
|
||||
import PlayingFrom from "./queue/playingFrom.vue";
|
||||
import UpNext from "./queue/upNext.vue";
|
||||
|
||||
const queue = useQStore();
|
||||
|
||||
const putCommas = perks.putCommas;
|
||||
|
||||
function playThis(track: Track) {
|
||||
queue.play(track);
|
||||
}
|
||||
@@ -64,53 +42,11 @@ function playThis(track: Track) {
|
||||
margin: 0.5rem 0 1rem 0;
|
||||
}
|
||||
|
||||
.main-item {
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
.itemx {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
cursor: pointer;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
&:hover {
|
||||
background-color: $gray;
|
||||
}
|
||||
}
|
||||
|
||||
.album-art {
|
||||
width: 4.5rem;
|
||||
height: 4.5rem;
|
||||
background-image: url(../../assets/images/null.webp);
|
||||
margin: 0 0.5rem 0 0;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.tags {
|
||||
hr {
|
||||
border: none;
|
||||
margin: 0.3rem;
|
||||
}
|
||||
.title {
|
||||
width: 20rem;
|
||||
margin: 0;
|
||||
}
|
||||
.artist {
|
||||
width: 20rem;
|
||||
margin: 0;
|
||||
font-size: small;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.r-grid {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-rows: min-content;
|
||||
grid-template-rows: max-content max-content 1fr;
|
||||
|
||||
.scrollable-r {
|
||||
height: 100%;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="r-tracks rounded border">
|
||||
<p class="heading">SIMILAR TRACKS</p>
|
||||
<div class="heading">Similar Tracks</div>
|
||||
<div class="tracks">
|
||||
<div class="song-item" v-for="song in songs" :key="song">
|
||||
<div class="album-art image"></div>
|
||||
@@ -37,8 +37,13 @@ export default {
|
||||
|
||||
<style lang="scss">
|
||||
.r-tracks {
|
||||
margin: 0.5rem 0.5rem 0.5rem 0;
|
||||
margin: 0.5rem 0 0.5rem 0;
|
||||
padding: 0.5rem;
|
||||
|
||||
.heading {
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: 0.5rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
.r-tracks .tracks .song-item {
|
||||
|
||||
@@ -170,7 +170,6 @@ search.$subscribe((mutation, state) => {
|
||||
padding: $medium;
|
||||
border-radius: $small;
|
||||
margin-bottom: $small;
|
||||
text-align: center !important;
|
||||
font-size: 2rem;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div id="playing-from" class="rounded" @click="goTo">
|
||||
<div class="abs shadow-sm">Playing From</div>
|
||||
<div class="h">
|
||||
<div class="icon image" :class="from.type"></div>
|
||||
{{ from.type }}
|
||||
</div>
|
||||
<div class="name">
|
||||
<div id="to">
|
||||
{{ from.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { fromFolder, fromAlbum, fromPlaylist } from "../../../interfaces";
|
||||
import { FromOptions } from "../../../composables/enums";
|
||||
import { useRouter } from "vue-router";
|
||||
import { computed } from "@vue/reactivity";
|
||||
|
||||
const props = defineProps<{
|
||||
from: fromFolder | fromAlbum | fromPlaylist;
|
||||
}>();
|
||||
|
||||
interface from {
|
||||
type: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const from = computed((): from => {
|
||||
switch (props.from.type) {
|
||||
case undefined:
|
||||
return {
|
||||
type: "album",
|
||||
name: "Welcome to Alice",
|
||||
};
|
||||
case FromOptions.folder:
|
||||
return {
|
||||
type: "folder",
|
||||
name: props.from.name,
|
||||
};
|
||||
case FromOptions.album:
|
||||
return {
|
||||
type: "album",
|
||||
name: props.from.name,
|
||||
};
|
||||
case FromOptions.playlist:
|
||||
return {
|
||||
type: "playlist",
|
||||
name: props.from.name,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
function goToAlbum() {
|
||||
router.push({
|
||||
name: "AlbumView",
|
||||
params: {
|
||||
album: props.from.name,
|
||||
artist: props.from.albumartist,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function goToFolder() {
|
||||
router.push({
|
||||
name: "FolderView",
|
||||
params: {
|
||||
path: props.from.path,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function goToPlaylist() {
|
||||
router.push({
|
||||
name: "PlaylistView",
|
||||
params: {
|
||||
pid: props.from.playlistid,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function goTo() {
|
||||
switch (props.from.type) {
|
||||
case FromOptions.folder:
|
||||
goToFolder();
|
||||
break;
|
||||
case FromOptions.album:
|
||||
goToAlbum();
|
||||
break;
|
||||
case FromOptions.playlist:
|
||||
goToPlaylist();
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#playing-from {
|
||||
background: linear-gradient(-200deg, $gray4 40%, $red, $gray4);
|
||||
background-size: 120%;
|
||||
padding: 0.75rem;
|
||||
margin-bottom: $small;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
transition: all .2s ease;
|
||||
|
||||
&:hover {
|
||||
background-position: -4rem;
|
||||
}
|
||||
|
||||
.abs {
|
||||
position: absolute;
|
||||
right: $small;
|
||||
top: $small;
|
||||
font-size: .9rem;
|
||||
background-color: $gray;
|
||||
padding: $smaller;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
text-transform: capitalize;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.h {
|
||||
font-size: .9rem;
|
||||
margin-bottom: $small;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $small;
|
||||
text-transform: capitalize;
|
||||
color: rgba(255, 255, 255, 0.664);
|
||||
|
||||
.icon {
|
||||
height: 1.25rem;
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.folder {
|
||||
background-image: url("../../../assets/icons/folder.fill.svg") !important;
|
||||
}
|
||||
|
||||
.album {
|
||||
background-image: url("../../../assets/icons/album.svg") !important;
|
||||
}
|
||||
|
||||
.playlist {
|
||||
background-image: url("../../../assets/icons/playlist.svg") !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div class="main-item border" @click="playNext">
|
||||
<div class="h">#Up_Next</div>
|
||||
<div class="itemx shadow">
|
||||
<div
|
||||
class="album-art image"
|
||||
:style="{
|
||||
backgroundImage: `url("${next.image}")`,
|
||||
}"
|
||||
></div>
|
||||
<div class="tags">
|
||||
<p class="title ellip">{{ next.title }}</p>
|
||||
<hr />
|
||||
<p class="artist ellip">
|
||||
<span v-for="artist in perks.putCommas(next.artists)" :key="artist">{{
|
||||
artist
|
||||
}}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Track } from "../../../interfaces";
|
||||
import perks from "../../../composables/perks";
|
||||
|
||||
const props = defineProps<{
|
||||
next: Track;
|
||||
playNext: () => void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.main-item {
|
||||
border-radius: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background-color: $accent;
|
||||
border: 1px solid transparent;
|
||||
|
||||
.h {
|
||||
background-color: $black;
|
||||
}
|
||||
}
|
||||
|
||||
.h {
|
||||
position: absolute;
|
||||
right: $small;
|
||||
top: $small;
|
||||
font-size: 0.9rem;
|
||||
background-color: $accent;
|
||||
padding: $smaller;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.itemx {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.album-art {
|
||||
width: 4.5rem;
|
||||
height: 4.5rem;
|
||||
background-image: url(../../assets/images/null.webp);
|
||||
margin: 0 0.5rem 0 0;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.tags {
|
||||
hr {
|
||||
border: none;
|
||||
margin: 0.3rem;
|
||||
}
|
||||
.title {
|
||||
width: 20rem;
|
||||
margin: 0;
|
||||
}
|
||||
.artist {
|
||||
width: 20rem;
|
||||
margin: 0;
|
||||
font-size: small;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -89,6 +89,7 @@ const context = useContextStore();
|
||||
position: absolute;
|
||||
right: -13rem;
|
||||
width: 13rem;
|
||||
top: -0.5rem;
|
||||
max-height: 21.25rem;
|
||||
|
||||
padding: $small !important;
|
||||
|
||||
@@ -35,11 +35,11 @@ function play() {
|
||||
break;
|
||||
case playSources.playlist:
|
||||
queue.playFromPlaylist(
|
||||
playlist.playlist.name,
|
||||
playlist.playlist.playlistid,
|
||||
playlist.playlist.tracks
|
||||
playlist.info.name,
|
||||
playlist.info.playlistid,
|
||||
playlist.tracks
|
||||
);
|
||||
queue.play(playlist.playlist.tracks[0]);
|
||||
queue.play(playlist.tracks[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -53,11 +53,7 @@ function play() {
|
||||
height: 2.5rem;
|
||||
padding-left: 0.75rem;
|
||||
cursor: pointer;
|
||||
background: linear-gradient(
|
||||
34deg,
|
||||
rgba(255, 166, 0, 0.644) 30%,
|
||||
rgb(214, 188, 38)
|
||||
);
|
||||
background: linear-gradient(34deg, $accent, $red);
|
||||
user-select: none;
|
||||
transition: all 0.5s ease;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user