add bottom bar

This commit is contained in:
geoffrey45 2022-01-28 16:46:24 +03:00
parent 13ee2ed1d6
commit 17c9f3a23e
10 changed files with 352 additions and 159 deletions

View File

@ -28,6 +28,9 @@
<UpNext v-model:up_next="up_next" @expandQueue="expandQueue" />
<RecommendedArtist />
</div>
<div class="bottom-bar">
<BottomBar />
</div>
</div>
</template>
@ -35,12 +38,12 @@
import { ref } from "@vue/reactivity";
import Navigation from "./components/LeftSidebar/Navigation.vue";
import PinnedStuff from "./components/LeftSidebar/PinnedStuff.vue";
import PinnedStuff from "./components/LeftSidebar/PinnedStuff.vue"
import Search from "./components/Search.vue";
import NowPlaying from "./components/RightSideBar/NowPlaying.vue";
import UpNext from "./components/RightSideBar/UpNext.vue";
import RecommendedArtist from "./components/RightSideBar/Recommendation.vue";
import BottomBar from "@/components/BottomBar/BottomBar.vue";
import perks from "@/composables/perks.js";
@ -52,6 +55,7 @@ export default {
NowPlaying,
UpNext,
RecommendedArtist,
BottomBar
},
setup() {

View File

@ -0,0 +1,93 @@
.b-bar {
height: 100%;
// padding: 0 $small 0 $small;
.prog {
display: grid;
}
.grid {
display: grid;
height: 100%;
// grid-auto-columns: 1fr;
// grid-auto-flow: column;
grid-template-columns: 1fr 3fr 1fr;
@include phone-only {
grid-template-columns: 1fr 9.2rem;
}
.info {
display: flex;
padding-top: $small;
margin-left: $small;
.art {
width: 3rem;
height: 3rem;
border-radius: $smaller;
background-image: url("../../images/eggs.jpg");
}
.separator {
margin: 2px;
}
.desc {
width: calc(100% - 5rem);
margin-left: $small;
display: flex;
align-items: center;
margin-top: -$small;
.artists {
font-size: 0.8rem;
color: $highlight-blue;
}
}
}
.controlsx {
// border: solid 1px;
width: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: flex-end;
@include phone-only {
// width: min-content;
}
.controls-bottom {
// border: solid 1px;
width: min-content;
.shuffle, .fav {
@include phone-only {
display: none !important;
}
}
}
.progress-bottom {
width: 100%;
.durationx {
background-color: #202020;
padding: $smaller;
border-radius: .4rem;
margin: 0 $small 0 $small;
}
// display: none;
}
}
.volume-group {
@include tablet-portrait {
display: none;
}
}
}
}

View File

@ -2,10 +2,11 @@
$card-dark: #08090c;
$red: #df4646;
$blue: rgb(5, 80, 150);
$green: rgb(67, 148, 67);
$blue: #055096;
$green: #439443;
$separator: #ffffff46;
$pink: rgb(196, 58, 58);
$pink: #c43a3a;
$highlight-blue: #006eff;
// sizes
$small: 0.5em;
$smaller: 0.25em;

View File

@ -79,7 +79,11 @@ button {
grid-template-columns: min-content 4fr min-content;
grid-template-rows: 4rem 1fr 1fr;
grid-auto-flow: row;
grid-template-areas: "l-sidebar content r-sidebar" "l-sidebar content r-sidebar" "l-sidebar content r-sidebar";
grid-template-areas:
"l-sidebar content r-sidebar"
"l-sidebar content r-sidebar"
"l-sidebar content r-sidebar"
"bottom-bar bottom-bar bottom-bar";
width: 100vw;
height: 100vh;
background-repeat: no-repeat;
@ -97,6 +101,13 @@ button {
background-color: $card-dark;
}
.bottom-bar {
grid-area: bottom-bar;
height: 4rem;
// margin: 0 $small 0 $small;
// display: none;
}
.collapsed .l-sidebar {
width: 70px;
transition: all 0.3s ease;
@ -263,3 +274,147 @@ button {
background-color: rgb(170, 50, 50);
}
}
.progress {
display: flex;
align-items: center;
position: relative;
.duration {
position: absolute;
right: 0;
top: -1rem;
font-size: small;
}
input {
-webkit-appearance: none;
width: 100%;
border: none;
outline: none;
background: transparent;
}
input:focus {
outline: none;
}
input::-webkit-slider-runnable-track {
width: 100%;
height: 0.25rem;
cursor: pointer;
background: #252829;
// background: linear-gradient(to right, #1488cc, #2b32b2);
}
input::-webkit-slider-thumb {
-webkit-appearance: none;
height: 1rem;
width: 1rem;
border-radius: 50%;
background: #ffffff;
cursor: pointer;
margin-top: -0.35rem;
}
input:focus::-webkit-slider-runnable-track,
input::-moz-range-track {
background: #367ebd;
}
input::-moz-range-thumb {
height: 1rem;
width: 1rem;
border-radius: 50%;
background: #ffffff;
cursor: pointer;
margin-top: -0.35rem;
}
}
.controls {
display: grid;
grid-template-columns: repeat(3, 1fr);
.nav {
display: grid;
grid-template-columns: repeat(3, 1fr);
width: 100%;
& * {
height: 3rem;
width: 3rem;
background-size: 50%;
cursor: pointer;
border-radius: 0.5rem;
}
#previous {
background-image: url(../../assets/icons/previous.svg);
}
.play-pause {
background-image: url(../../assets/icons/play.svg);
}
.isPlaying {
background-image: url(../../assets/icons/pause.svg);
}
#next {
background-image: url(../../assets/icons/next.svg);
}
}
.shuffle {
width: 100%;
display: flex;
align-items: center;
& * {
height: 2rem;
width: 2rem;
background-size: 70%;
cursor: pointer;
border-radius: 0.5rem;
}
& :first-child {
background-image: url(../../assets/icons/repeat.svg);
}
& :last-child {
background-image: url(../../assets/icons/shuffle.svg);
}
}
.fav {
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
& * {
height: 2rem;
width: 2rem;
background-size: 70%;
border-radius: 0.5rem;
cursor: pointer;
}
& :first-child {
background-image: url(../../assets/icons/plus.svg);
}
& :last-child {
background-image: url(../../assets/icons/heart.svg);
}
}
.fav *:hover,
.shuffle *:hover,
.nav *:hover {
background-color: rgb(5, 80, 150);
}
}

View File

@ -0,0 +1,52 @@
<template>
<div class="b-bar border card-dark">
<div class="grid">
<SongCard />
<div class="controlsx">
<div class="controls controls-bottom">
<div class="nav">
<div class="image" id="previous" @click="playPrev"></div>
<div
class="image play-pause"
@click="playPause"
:class="{ isPlaying: isPlaying }"
></div>
<div class="image" id="next" @click="playNext"></div>
</div>
</div>
<div class="progress progress-bottom">
<span class="durationx">0:45</span>
<input
id="progress"
type="range"
:value="pos"
min="0"
max="1000"
@change="seek()"
/>
<span class="durationx">3:55</span>
</div>
</div>
<div class="prog"></div>
<div class="volume-group"></div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import "../../assets/css/BottomBar/BottomBar.scss";
import playAudio from "../../composables/playAudio";
import SongCard from "./SongCard.vue";
const pos = ref(playAudio.pos);
const isPlaying = ref(playAudio.playing);
const seek = () => {
playAudio.seek(document.getElementById("progress").value);
};
const { playNext } = playAudio;
const { playPrev } = playAudio;
const { playPause } = playAudio;
</script>

View File

@ -0,0 +1,33 @@
<template>
<div class="info">
<div
class="image art"
:style="{
backgroundImage: `url(&quot;${track.image}&quot;)`,
}"
></div>
<div class="desc">
<div>
<div class="title ellip">{{ track.title }}</div>
<div class="separator no-border"></div>
<div class="artists ellip" v-if="track.artists[0] != ''">
<span v-for="artist in putCommas(track.artists)" :key="artist">{{
artist
}}</span>
</div>
<div class="artists" v-else>
<span>{{ track.album_artist }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import perks from "../../composables/perks";
const track = ref(perks.current);
const putCommas = perks.putCommas;
</script>

View File

@ -99,7 +99,7 @@ function loadAlbum(title, album_artist) {
}
.current * {
color: rgb(0, 110, 255);
color: $highlight-blue;
}
.current:hover {

View File

@ -101,153 +101,7 @@ export default {
display: grid;
grid-template-rows: 3fr 1fr;
.progress {
display: flex;
align-items: center;
height: 1.5rem;
position: relative;
.duration {
position: absolute;
right: 0;
top: -1rem;
font-size: small;
}
input {
-webkit-appearance: none;
width: 100%;
border: none;
outline: none;
background: transparent;
}
input:focus {
outline: none;
}
input::-webkit-slider-runnable-track {
width: 100%;
height: 0.25rem;
cursor: pointer;
background: #1488cc;
background: linear-gradient(
to right,
#1488cc,
#2b32b2
);
}
input::-webkit-slider-thumb {
-webkit-appearance: none;
height: 1rem;
width: 1rem;
border-radius: 50%;
background: #ffffff;
cursor: pointer;
margin-top: -0.35rem;
}
input:focus::-webkit-slider-runnable-track,
input::-moz-range-track {
background: #367ebd;
}
input::-moz-range-thumb {
height: 1rem;
width: 1rem;
border-radius: 50%;
background: #ffffff;
cursor: pointer;
margin-top: -0.35rem;
}
}
.controls {
display: grid;
grid-template-columns: repeat(3, 1fr);
.nav {
display: grid;
grid-template-columns: repeat(3, 1fr);
width: 100%;
& * {
height: 3rem;
width: 3rem;
background-size: 50%;
cursor: pointer;
border-radius: 0.5rem;
}
#previous {
background-image: url(../../assets/icons/previous.svg);
}
.play-pause {
background-image: url(../../assets/icons/play.svg);
}
.isPlaying {
background-image: url(../../assets/icons/pause.svg);
}
#next {
background-image: url(../../assets/icons/next.svg);
}
}
.shuffle {
width: 100%;
display: flex;
align-items: center;
& * {
height: 2rem;
width: 2rem;
background-size: 70%;
cursor: pointer;
border-radius: 0.5rem;
}
& :first-child {
background-image: url(../../assets/icons/repeat.svg);
}
& :last-child {
background-image: url(../../assets/icons/shuffle.svg);
}
}
.fav {
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
& * {
height: 2rem;
width: 2rem;
background-size: 70%;
border-radius: 0.5rem;
cursor: pointer;
}
& :first-child {
background-image: url(../../assets/icons/plus.svg);
}
& :last-child {
background-image: url(../../assets/icons/heart.svg);
}
}
.fav *:hover,
.shuffle *:hover,
.nav *:hover {
background-color: rgb(5, 80, 150);
}
}
.art-tags {
display: flex;

View File

@ -22,10 +22,6 @@ export default {
title: "Mockingbird",
artist: "Eminem",
},
{
title: "Slim shady",
artist: "Eminem",
},
];
const r_albums = ["Crybaby", "Everybody's Everything", "Castles II"];

View File

@ -15,7 +15,7 @@ const playAudio = (path) => {
new Promise((resolve, reject) => {
audio.src = full_path;
audio.onloadeddata = resolve;
audio.oncanplaythrough = resolve;
audio.onerror = reject;
})
.then(() => {
@ -26,6 +26,7 @@ const playAudio = (path) => {
audio.ontimeupdate = () => {
pos.value = (audio.currentTime / audio.duration) * 1000;
};
})
.catch((err) => console.log(err));
@ -71,3 +72,7 @@ audio.addEventListener("ended", () => {
});
export default { playAudio, playNext, playPrev, playPause, seek, pos, playing };
// TODO
// Try implementing classes to play audio .ie. Make the seek, playNext, playPrev, etc the methods of a class. etc