Introduce tabs to right sidebar

- new icons
- rename upnext.vue to queue.vue
- other tiny changes
This commit is contained in:
geoffrey45
2022-01-31 09:38:14 +03:00
parent 3eef90dc8a
commit bdfbb59d76
19 changed files with 363 additions and 255 deletions
+14
View File
@@ -0,0 +1,14 @@
<template>
<div class="r-home image">
</div>
</template>
<style lang="scss">
.r-home {
height: 100%;
width: 31rem;
background-image: url("https://pro2-bar-s3-cdn-cf2.myportfolio.com/a534e2586a621751e93466e77f5228be/d686c78b-9cd7-4eeb-a660-69cfaf7e4cac_rw_600.gif");
color: transparent;
}
</style>
+70 -25
View File
@@ -1,20 +1,25 @@
<template>
<div class="r-sidebar">
<!-- <div class="m-np"> -->
<!-- <NowPlaying class="hidden"/> -->
<!-- </div> -->
<div class="s">
<Search
v-model:search="search"
@expandSearch="expandSearch"
@collapseSearch="collapseSearch"
/>
</div>
<div class="q">
<UpNext v-model:up_next="up_next" @expandQueue="expandQueue" />
</div>
<div class="r">
<RecommendedArtist />
<div class="grid">
<div class="r-content border rounded">
<div class="r-dash" v-if="current_tab == tabs.home">
<DashBoard/>
</div>
<div class="r-search" v-if="current_tab == tabs.search">
<Search
v-model:search="search"
@expandSearch="expandSearch"
@collapseSearch="collapseSearch"
/>
</div>
<div class="r-queue" v-if="current_tab == tabs.queue">
<UpNext v-model:up_next="up_next" @expandQueue="expandQueue" />
</div>
</div>
<div class="tab-keys card-dark border">
<Tabs :current_tab="current_tab" :tabs="tabs" @changeTab="changeTab" />
</div>
</div>
</div>
</template>
@@ -22,8 +27,11 @@
<script setup>
import { ref } from "vue";
import Search from "../Search.vue";
import UpNext from "./UpNext.vue";
import RecommendedArtist from "@/components/RightSideBar/Recommendation.vue";
import UpNext from "./Queue.vue";
import Tabs from "./Tabs.vue";
import Main from "./Home/Main.vue";
const DashBoard = Main;
let up_next = ref(true);
let search = ref(false);
@@ -39,17 +47,54 @@ const expandSearch = () => {
const collapseSearch = () => {
search.value = false;
};
const tabs = {
home: "home",
search: "search",
queue: "queue",
};
const current_tab = ref(tabs.search);
function changeTab(tab) {
current_tab.value = tab;
}
</script>
<style lang="scss">
.r-sidebar {
border-radius: 5px;
margin-right: 0.5rem;
margin-bottom: $small;
overflow-y: auto;
width: 30em;
display: grid;
grid-auto-flow: row;
grid-template-rows: min-content min-content auto;
width: 34em;
.grid {
height: 100%;
display: grid;
grid-template-areas: "content tabs";
.r-content {
grid-area: content;
width: 100%;
overflow: hidden;
margin: $small $small $small 0;
.r-search {
height: 100%;
}
.r-dash {
height: 100%;
}
.r-queue {
height: 100%;
}
}
.tab-keys {
grid-area: tabs;
width: 3rem;
padding: $small;
margin-left: $small;
}
}
}
</style>
+144
View File
@@ -0,0 +1,144 @@
<template>
<div class="up-next border">
<p class="heading">COMING UP NEXT</p>
<div class="r-grid">
<div class="main-item h-1 border" @click="playNext">
<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 putCommas(next.artists)" :key="artist">{{
artist
}}</span>
</p>
</div>
</div>
<div class="scrollable-r border">
<TrackItem v-for="song in queue" :key="song" :track="song" />
</div>
</div>
</div>
</template>
<script>
import { ref, toRefs } from "@vue/reactivity";
import perks from "@/composables/perks.js";
import audio from "@/composables/playAudio.js";
import { watch } from "@vue/runtime-core";
import TrackItem from "../shared/TrackItem.vue";
export default {
props: ["up_next"],
setup(props, { emit }) {
const is_expanded = toRefs(props).up_next;
const queue = ref(perks.queue);
const next = ref(perks.next);
let collapse = () => {
emit("expandQueue");
};
watch(is_expanded, (newVal) => {
if (newVal) {
setTimeout(() => {
perks.focusCurrent();
}, 1000);
}
});
const { playNext } = audio;
const putCommas = perks.putCommas;
return {
collapse,
is_expanded,
playNext,
putCommas,
queue,
next,
};
},
components: { TrackItem },
};
</script>
<style lang="scss">
.up-next {
background-color: $card-dark;
border-radius: 0.5rem;
padding: $small;
overflow: hidden;
height: 100%;
.heading {
position: relative;
margin: 0.5rem 0 1rem 0;
}
.main-item {
display: flex;
align-items: center;
padding: 0.5rem;
border-radius: 0.5rem;
cursor: pointer;
margin-bottom: 0.5rem;
.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;
}
}
&:hover {
background-color: $blue;
}
}
.r-grid {
position: relative;
height: calc(100% - 2rem);
overflow: hidden;
width: 100%;
display: grid;
grid-template-rows: min-content 1fr;
.scrollable-r {
margin-bottom: $small;
padding: $small;
overflow: auto;
background-color: $card-dark;
border-radius: 0.5rem;
&::-webkit-scrollbar-track {
background-color: transparent;
}
}
}
}
</style>
+63
View File
@@ -0,0 +1,63 @@
<template>
<div class="r-tabs">
<button v-for="tab in props.tabs"
@click="changeTab(tab)"
:key="tab"
class="image t-item rounded"
:class="{ active_tab: props.current_tab == tab }, `${tab}`"
></button>
<div>
</div>
</div>
</template>
<script setup>import { onMounted } from 'vue';
const props = defineProps({
current_tab: String,
tabs: Object,
});
const emit = defineEmits(['changeTab'])
function changeTab(tab) {
if (tab == props.current_tab) return;
emit('changeTab', tab)
}
</script>
<style lang="scss">
.r-tabs {
display: flex;
flex-direction: column;
gap: $small;
.t-item {
width: 2rem;
height: 2rem;
background-size: 1.5rem;
}
.active_tab {
border-right: solid;
border-radius: $small 0 0 $small;
}
.search {
background-image: url("../../assets/icons/search.svg");
background-color: rgba(35, 35, 66, 0.247);
}
.queue {
background-image: url("../../assets/icons/queue.svg");
background-color: rgba(46, 25, 33, 0.445);
}
.home {
background-image: url("../../assets/icons/dashboard.svg");
background-color: rgba(148, 102, 50, 0.445);
}
}
</style>
-169
View File
@@ -1,169 +0,0 @@
<template>
<div class="up-next border">
<p class="heading">
COMING UP NEXT <span class="more" @click="collapse">SEE ALL</span>
</p>
<div class="main-item h-1 border" @click="playNext">
<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 putCommas(next.artists)" :key="artist">{{
artist
}}</span>
</p>
</div>
</div>
<div>
<div
:class="{ v0: !is_expanded, v1: is_expanded }"
class="scrollable border"
>
<TrackItem v-for="song in queue" :key="song" :track="song" />
</div>
</div>
</div>
</template>
<script>
import { ref, toRefs } from "@vue/reactivity";
import perks from "@/composables/perks.js";
import audio from "@/composables/playAudio.js";
import { watch } from "@vue/runtime-core";
import TrackItem from "../shared/TrackItem.vue";
export default {
props: ["up_next"],
setup(props, { emit }) {
const is_expanded = toRefs(props).up_next;
const queue = ref(perks.queue);
const next = ref(perks.next);
let collapse = () => {
emit("expandQueue");
};
watch(is_expanded, (newVal) => {
if (newVal) {
setTimeout(() => {
perks.focusCurrent();
}, 1000);
}
});
const { playNext } = audio;
const putCommas = perks.putCommas;
return {
collapse,
is_expanded,
playNext,
putCommas,
queue,
next,
};
},
components: { TrackItem },
};
</script>
<style lang="scss">
.up-next .v0 {
max-height: 0;
transition: max-height 0.5s ease;
visibility: hidden;
padding: 0;
}
.up-next .v1 {
max-height: 21em;
transition: max-height 0.5s ease;
padding: $small;
.currentInQueue {
border: 2px solid $pink;
&:hover {
color: #fff;
}
}
}
.up-next {
padding: 0.5rem;
margin-top: $small;
background-color: $card-dark;
border-radius: 0.5rem;
}
.up-next .heading {
position: relative;
margin: 0.5rem 0 1rem 0;
span {
position: absolute;
right: 0.5rem;
padding: 0.5rem;
border-radius: 0.5rem;
user-select: none;
&:hover {
background: $blue;
cursor: pointer;
}
}
}
.up-next .main-item {
display: flex;
align-items: center;
padding: 0.5rem;
border-radius: 0.5rem;
cursor: pointer;
margin-bottom: 0.5rem;
.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;
}
}
&:hover {
background-color: $blue;
}
}
.up-next .scrollable {
overflow-y: auto;
background-color: $card-dark;
border-radius: 0.5rem;
&::-webkit-scrollbar-track {
background-color: transparent;
}
}
</style>