🔷 add PlayingFrom component to right sidebar

🔷 move upNext card into separate component
🔷 a lot of refactors
This commit is contained in:
geoffrey45
2022-04-03 21:47:57 +03:00
parent 334cf0fce1
commit 6cf9a58d6d
26 changed files with 425 additions and 220 deletions
+15 -24
View File
@@ -4,47 +4,38 @@
<div
class="image art shadow-lg rounded"
:style="{
backgroundImage: `url(&quot;${props.album_info.image}&quot;)`,
backgroundImage: `url(&quot;${props.album.image}&quot;)`,
}"
></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>
+6 -13
View File
@@ -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;
+10 -5
View File
@@ -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>
+5 -69
View File
@@ -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(&quot;${queue.next.image}&quot;)`,
}"
></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 {
-1
View File
@@ -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(&quot;${next.image}&quot;)`,
}"
></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>
+1
View File
@@ -89,6 +89,7 @@ const context = useContextStore();
position: absolute;
right: -13rem;
width: 13rem;
top: -0.5rem;
max-height: 21.25rem;
padding: $small !important;
+5 -9
View File
@@ -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;