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>
+29 -27
View File
@@ -1,33 +1,35 @@
<template>
<div class="right-search border" ref="searchComponent">
<div class="input">
<Loader />
<Filters :filters="filters" @removeFilter="removeFilter" />
<div class="input-loader border">
<input
type="search"
id="search"
@focus="activateMagicFlag"
@blur="removeMagicFlag"
@keyup.backspace="removeLastFilter"
placeholder="find your music"
v-model="query"
/>
<div class="search-icon image"></div>
<!-- -->
</div>
<div
class="suggestions v00"
:class="{
v00: !filters.length && !query,
v11: filters.length || query,
}"
>
<div class="item">Kenny Rogers</div>
<div class="right-search" ref="searchComponent">
<div>
<div class="input">
<Loader />
<Filters :filters="filters" @removeFilter="removeFilter" />
<div class="input-loader border">
<input
type="text"
id="search"
@focus="activateMagicFlag"
@blur="removeMagicFlag"
@keyup.backspace="removeLastFilter"
placeholder="find your music"
v-model="query"
/>
<div class="search-icon image"></div>
<!-- -->
</div>
<div
class="suggestions v00"
:class="{
v00: !filters.length && !query,
v11: filters.length || query,
}"
>
<div class="item">Kenny Rogers</div>
</div>
</div>
<div class="separator no-border"></div>
<Options :magic_flag="magic_flag" @addFilter="addFilter" />
</div>
<div class="separator no-border"></div>
<Options :magic_flag="magic_flag" @addFilter="addFilter" />
<div class="scrollable" :class="{ v0: !is_hidden, v1: is_hidden }">
<TracksGrid
:tracks="tracks.tracks"
-1
View File
@@ -35,7 +35,6 @@ export default {
border-radius: 0.5rem;
background: #0f131b44;
margin-left: $small;
margin-top: $small;
padding: $small 0;
overflow-x: hidden;
+1 -1
View File
@@ -38,8 +38,8 @@ export default {
.right-search .artists-results {
border-radius: 0.5rem;
background: #1214178c;
margin: 0 0 0 $small;
padding: $small 0;
margin-bottom: $small;
.grid {
padding: 0 0 0 $small;
+2 -1
View File
@@ -29,9 +29,10 @@ export default {
<style lang="scss">
.right-search .filter {
display: flex;
margin-left: 3rem;
margin-left: 2rem;
height: 2rem;
.item {
&:hover {
width: 4rem;
+1 -1
View File
@@ -1,7 +1,7 @@
<template>
<div class="morexx">
<button @click="loadMore">
<div class="text">Load All</div>
<div class="text">Load More</div>
</button>
</div>
</template>
+4 -6
View File
@@ -1,6 +1,6 @@
<template>
<div class="loaderx" :class="{ loader: loading, not_loader: !loading }">
<div class="content" v-if="!loading">/</div>
<div v-if="!loading">😹</div>
</div>
</template>
@@ -18,15 +18,14 @@ export default {
<style lang="scss">
.loaderx {
position: absolute;
left: 0.65rem;
top: 0.65rem;
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
}
.loader {
border: dotted $blue;
border-radius: 50%;
animation: spin 0.25s linear infinite;
@keyframes spin {
@@ -40,8 +39,7 @@ export default {
}
.not_loader {
border: solid 1px;
border-radius: 50%;
background-image: url("");
display: grid;
place-items: center;
}
</style>
+2 -1
View File
@@ -1,5 +1,5 @@
<template>
<div class="options" v-if="magic_flag">
<div class="options border rounded">
<div class="item info">Filter by:</div>
<div
class="item"
@@ -54,6 +54,7 @@ export default {
<style lang="scss">
.right-search .options {
display: flex;
margin-bottom: $small;
.item {
margin: $small;
-1
View File
@@ -41,7 +41,6 @@ function loadMore() {
<style lang="scss">
.right-search .tracks-results {
border-radius: 0.5rem;
margin-left: $small;
padding: $small;
}
</style>
+4
View File
@@ -51,6 +51,10 @@ const playThis = (song) => {
</script>
<style lang="scss">
.currentInQueue {
border: solid 2px $pink;
}
.track-item {
display: flex;
align-items: center;