server: add get album bio from last fm function

- co-written by Github Copilot
This commit is contained in:
geoffrey45
2022-01-17 12:32:27 +03:00
parent a720891c20
commit 2ee8d27bf0
20 changed files with 370 additions and 446 deletions
+46 -13
View File
@@ -1,10 +1,17 @@
<template>
<div class="al-bio rounded">
<div class="heading">ALBUM BIOGRAPHY</div>
<div class="heading">
The Very Best Of UB40: ALBUM BIOGRAPHY
<div class="tags">
<div class="item" v-for="tag in tags" :key="tag">
{{ tag }}
</div>
</div>
</div>
<div class="separator"></div>
<div class="content">
Two years after he prematurely left us, the Juice WRLD story continues
with Fighting Demons. The rappers second posthumous album dropped at
with Fighting Demons. The rapper's second posthumous album dropped at
midnight, and is the followup to Legends Never Die, which arrived in July
2020 and hit No. 1 on the Billboard 200 chart.
<br /><br />
@@ -15,22 +22,29 @@
Higgins) was just 21 when he died of an accidental overdose of oxycodone
and codeine. Following his death on Dec. 9, 2019, his mother, Carmela
Wallace, created the Live Free 999 Fund, to help youth struggling with
mental health and substance use issues.
<br><br>
Jarad was always searingly honest
about his struggles and through his musical genius he articulated what was
on his heart and mind vividly through his art. He never gave up and his
friends and family never gave up on offering their support to him, she
continued. We encourage all of you who struggle with addiction and mental
health to never give up the fight. Juices fast rise in the hip-hop space
and untimely passing is the focus of Into the Abyss, a Tommy
Oliver-directed documentary set to premiere Dec. 16 at 8PM on HBO Max.
mental health and substance use issues.
<br /><br />
“Jarad was always searingly honest about his struggles and through his
musical genius he articulated what was on his heart and mind vividly
through his art. He never gave up and his friends and family never gave up
on offering their support to him,” she continued. “We encourage all of you
who struggle with addiction and mental health to never give up the fight."
Juice's fast rise in the hip-hop space and untimely passing is the focus
of Into the Abyss, a Tommy Oliver-directed documentary set to premiere
Dec. 16 at 8PM on HBO Max.
</div>
</div>
</template>
<script>
export default {};
export default {
setup() {
const tags = ["reggea", "ub40", "ali campbell", "astro"];
return {
tags,
};
},
};
</script>
<style lang="scss">
@@ -40,6 +54,25 @@ export default {};
.heading {
margin: 0 0 0 $small;
height: 2rem;
position: relative;
.tags {
position: absolute;
right: 0;
display: flex;
font-weight: normal;
.item {
padding: $small;
background-color: rgb(15, 74, 114);
margin-left: $small;
border-radius: $small;
}
.item::before {
content: "#"
}
}
}
.content {
+42 -75
View File
@@ -1,30 +1,27 @@
<template>
<div class="folder">
<div class="table rounded" ref="songtitle" v-if="songs.length">
<div class="table rounded" v-if="songs.length">
<table>
<thead>
<tr>
<th>Track</th>
<th>Artist</th>
<th>Album</th>
<th v-if="songTitleWidth > minWidth">Duration</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
<SongItem
:songTitleWidth="songTitleWidth"
:minWidth="minWidth"
v-for="song in songs"
:key="song"
:song="song"
:current="current"
@updateQueue="updateQueue"
@loadAlbum="loadAlbum"
/>
</tbody>
</table>
</div>
<div ref="songtitle" v-else-if="songs.length === 0 && search_query">
<div v-else-if="songs.length === 0 && search_query">
<div class="no-results">
<div class="icon"></div>
<div class="text"> Track not found!</div>
@@ -36,7 +33,7 @@
<script>
import { ref } from "@vue/reactivity";
import { onMounted, onUnmounted } from "@vue/runtime-core";
import { onMounted } from "@vue/runtime-core";
import SongItem from "../SongItem.vue";
import album from "@/composables/album.js";
@@ -50,40 +47,14 @@ export default {
SongItem,
},
setup() {
const songtitle = ref(null);
const songTitleWidth = ref(null);
const minWidth = ref(300);
let routex;
const current = ref(perks.current);
const search_query = ref(state.search_query);
const route = useRouter();
const resizeSongTitleWidth = () => {
try {
let a = songtitle.value.clientWidth;
songTitleWidth.value = a > minWidth.value * 4 ? a / 4 : a / 3;
} catch (error) {
return;
}
};
onMounted(() => {
routex = useRoute().name;
resizeSongTitleWidth();
window.addEventListener("resize", () => {
resizeSongTitleWidth();
});
});
onUnmounted(() => {
window.removeEventListener("resize", () => {
resizeSongTitleWidth();
});
});
function updateQueue(song) {
@@ -91,10 +62,10 @@ export default {
switch (routex) {
case "FolderView":
type = "folder";
type = "folder";
break;
case "AlbumView":
type = "album";
type = "album";
break;
}
@@ -122,9 +93,6 @@ export default {
return {
updateQueue,
loadAlbum,
songtitle,
songTitleWidth,
minWidth,
current,
search_query,
};
@@ -161,49 +129,48 @@ export default {
}
}
.folder .table table td .album-art {
width: 3rem;
height: 3rem;
margin-right: 1rem;
background-image: url(../../assets/images/null.webp);
display: grid;
place-items: center;
}
.folder .table .flex {
position: relative;
align-items: center;
}
.folder .table .flex > div > span {
position: absolute;
bottom: 1.5rem;
width: calc(100% - 6rem);
}
td,
th {
padding: $small 0 $small $small;
text-align: left;
}
th {
text-transform: uppercase;
font-weight: normal;
// display: none;
}
td .artist {
margin-right: 0.2rem;
}
.folder .table table {
border-collapse: collapse;
text-transform: capitalize;
position: relative;
width: 100%;
table-layout: fixed;
thead {
height: 2rem;
text-transform: uppercase;
th {
text-align: left;
padding-left: $small;
}
}
tbody tr {
cursor: pointer;
transition: all 0.1s ease;
.flex {
position: relative;
padding-left: 4rem;
align-items: center;
.album-art {
position: absolute;
left: $small;
width: 3rem;
height: 3rem;
margin-right: 1rem;
background-image: url(../../assets/images/null.webp);
display: grid;
place-items: center;
}
}
td {
height: 4rem;
padding: $small;
}
&:hover {
& {
+13 -8
View File
@@ -73,15 +73,20 @@ export default {
</script>
<style lang="scss">
.collapsed .nav-button {
font-size: smaller;
margin-top: 5px;
align-items: center;
justify-content: center;
.collapsed {
.nav-button {
font-size: smaller;
margin-top: 5px;
align-items: center;
justify-content: center;
.in {
width: 100%;
flex-direction: column;
span {
display: none;
}
.in {
width: 100%;
flex-direction: column;
}
}
}
+35 -35
View File
@@ -5,7 +5,7 @@
<div class="next" @click="scrollRight"></div>
</div>
<div class="artists" ref="artists_dom" v-on:mouseover="scrollArtists">
<div class="artist c1">
<div class="artist c1 image">
<div class="blur"></div>
<div class="s2"></div>
<p>Featured Artists</p>
@@ -74,7 +74,7 @@ export default {
<style lang="scss">
.f-artists {
position: relative;
height: 13em;
height: 15em;
width: calc(100%);
background-color: $card-dark;
padding: $small;
@@ -143,69 +143,69 @@ export default {
margin-left: $smaller;
margin-right: $smaller;
width: 9em;
height: 9em;
height: 11em;
border-radius: $small;
background-color: #0f0e0e;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.5s ease-in-out;
cursor: pointer;
border: solid 1px rgba(165, 151, 151, 0.055);
.artist-image {
width: 7em;
height: 7em;
margin-left: 0.5em;
border-radius: 50%;
margin-bottom: $small;
background: url(../../assets/images/girl1.jpg);
background-size: cover;
background-size: 7rem 7rem;
background-repeat: no-repeat;
background-position: center;
transition: all 0.75s ease-in-out;
border: solid 1px rgba(165, 151, 151, 0.055);
box-shadow: 0px 0px 80px rgb(0, 0, 0);
}
&:hover {
.artist-image {
background-position: 50% 20%;
border-radius: 20%;
background-size: 10rem 10rem;
}
}
.artist-name {
margin: 0;
text-align: center;
font-size: small;
width: 10em;
}
&:hover {
transform: translateY(-0.5em);
transition: all 0.5s ease-in-out;
font-size: 0.9rem;
font-weight: 510;
max-width: 7rem;
}
}
.f-artists .c1 {
position: relative;
background: rgb(16, 25, 51);
width: 15em;
background-size: 400px 11rem;
background-position: 100%;
&:hover > .s2 {
background: rgba(53, 53, 146, 0.8);
transition: all 0.5s ease;
width: 12em;
height: 12em;
background-image: linear-gradient(
320deg,
hsl(0deg 3% 6%) 13%,
hsl(211deg 81% 23%) 50%,
hsl(209deg 94% 30%) 87%
);
transition: all 0.75s ease-in-out;
&:hover {
background-position: 10%;
}
p {
position: absolute;
bottom: -2rem;
margin-left: 0.5rem;
font-size: 2rem;
margin-left: 1rem;
font-size: 1.5rem;
font-weight: 700;
color: #ffffff;
}
.s2 {
position: absolute;
left: -2em;
bottom: -4em;
width: 10em;
height: 10em;
background: rgba(53, 53, 146, 0.445);
border-radius: 50%;
transition: all 0.5s ease;
text-shadow: 0px 0px 80px rgb(0, 0, 0);
}
}
</style>
-94
View File
@@ -1,94 +0,0 @@
<template>
<div class="folder" id="p-table">
<div class="table rounded" ref="songtitle">
<table>
<tr>
<th>Track</th>
<th>Artist</th>
<th>Album</th>
<th v-if="songTitleWidth > minWidth">Duration</th>
</tr>
<tr v-for="song in songs" :key="song">
<td :style="{ width: songTitleWidth + 'px' }" class="flex">
<div class="album-art rounded image"></div>
<div>
<span class="ellipsis">{{ song.title }}</span>
</div>
</td>
<td :style="{ width: songTitleWidth + 'px' }">
<span class="artist" v-for="artist in song.artists" :key="artist">{{
artist
}}</span>
</td>
<td :style="{ width: songTitleWidth + 'px' }">{{ song.album }}</td>
<td
:style="{ width: songTitleWidth + 'px' }"
v-if="songTitleWidth > minWidth"
>
{{ song.duration }}
</td>
</tr>
</table>
</div>
</div>
</template>
<script>
import { ref } from "@vue/reactivity";
import { onMounted, onUnmounted } from "@vue/runtime-core";
import Songs from "../../data/songs.js";
export default {
setup() {
const songtitle = ref(null);
const songTitleWidth = ref(null);
const minWidth = ref(300);
const songs = Songs.songs;
const resizeSongTitleWidth = () => {
let a = songtitle.value.clientWidth;
songTitleWidth.value = a > minWidth.value * 4 ? a / 4 : a / 3;
};
onMounted(() => {
resizeSongTitleWidth();
window.addEventListener("resize", () => {
resizeSongTitleWidth();
});
});
onUnmounted(() => {
window.removeEventListener("resize", () => {
resizeSongTitleWidth();
});
});
return { songtitle, songTitleWidth, songs, minWidth };
},
};
</script>
<style lang="scss">
#p-table {
height: calc(100% - 0rem) !important;
overflow: hidden;
padding-bottom: 0rem;
table {
&::-webkit-scrollbar {
display: none;
}
th {
position: sticky;
background-color: rgb(58, 57, 57);
top: 0;
z-index: 5;
}
}
}
</style>
+2 -2
View File
@@ -276,8 +276,8 @@ export default {
border-radius: 0.5rem;
margin-right: 0.5rem;
margin-left: $small;
background-color: #ad1717a8;
background-image: url(../../assets/images/null.webp);
// background-color: #ad1717a8;
background-image: url("../../assets/images/null.webp");
}
}
}
+3 -6
View File
@@ -1,7 +1,6 @@
<template>
<tr :class="{ current: current._id.$oid == song._id.$oid }">
<td
:style="{ width: songTitleWidth + 'px' }"
class="flex"
@click="emitUpdate(song)"
>
@@ -21,7 +20,7 @@
<span class="ellip">{{ song.title }}</span>
</div>
</td>
<td :style="{ width: songTitleWidth + 'px' }">
<td>
<div class="ellip" v-if="song.artists[0] != ''">
<span
class="artist"
@@ -34,7 +33,7 @@
<span class="artist">{{ song.album_artist }}</span>
</div>
</td>
<td :style="{ width: songTitleWidth + 'px' }">
<td>
<div
class="ellip"
@click="emitLoadAlbum(song.album, song.album_artist)"
@@ -42,8 +41,6 @@
>
</td>
<td
:style="{ width: songTitleWidth + 'px' }"
v-if="songTitleWidth > minWidth"
>
{{ `${Math.trunc(song.length / 60)} min` }}
</td>
@@ -55,7 +52,7 @@ import perks from "@/composables/perks.js";
import state from "@/composables/state.js";
export default {
props: ["song", "songTitleWidth", "minWidth"],
props: ["song"],
setup(props, { emit }) {
function emitUpdate(song) {
emit("updateQueue", song);