mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 04:23:01 +00:00
server: add get album bio from last fm function
- co-written by Github Copilot
This commit is contained in:
@@ -7,5 +7,4 @@ $green: rgb(67, 148, 67);
|
||||
$separator: #ffffff46;
|
||||
// sizes
|
||||
$small: .5em;
|
||||
$smaller: .25em;
|
||||
|
||||
$smaller: .25em;
|
||||
@@ -74,18 +74,6 @@ button {
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background: rgba(0, 0, 0, 0.575);
|
||||
backdrop-filter: blur(40px);
|
||||
-webkit-backdrop-filter: blur(40px);
|
||||
-moz-backdrop-filter: blur(40px);
|
||||
}
|
||||
|
||||
#bg-blur {
|
||||
position: absolute;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: rgba(27, 27, 27, 0.548);
|
||||
background-image: url(../images/dark-bg.jpg);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.l-sidebar {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -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 rapper’s 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.” 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.
|
||||
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 {
|
||||
|
||||
@@ -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 {
|
||||
& {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -10,6 +10,7 @@ const current = ref(state.current);
|
||||
const next = ref({
|
||||
title: "The next song",
|
||||
artists: ["... blah blah blah"],
|
||||
image: "http://127.0.0.1:8900/images/defaults/4.webp",
|
||||
_id: {
|
||||
$oid: "",
|
||||
},
|
||||
|
||||
@@ -6,18 +6,20 @@ const queue = ref([
|
||||
{
|
||||
title: "Nothing played yet",
|
||||
artists: ["... blah blah blah"],
|
||||
image: "http://127.0.0.1:8900/images/defaults/5.webp",
|
||||
_id: {
|
||||
$oid: "",
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const folder_song_list = ref([])
|
||||
const folder_list = ref([])
|
||||
const folder_song_list = ref([]);
|
||||
const folder_list = ref([]);
|
||||
|
||||
const current = ref({
|
||||
title: "Nothing played yet",
|
||||
artists: ["... blah blah blah"],
|
||||
image: "http://127.0.0.1:8900/images/defaults/1.webp",
|
||||
_id: {
|
||||
$oid: "",
|
||||
},
|
||||
@@ -31,9 +33,9 @@ const prev = ref({
|
||||
},
|
||||
});
|
||||
|
||||
const album_song_list = ref([])
|
||||
const album_info = ref([])
|
||||
const album_artists = ref([])
|
||||
const album_song_list = ref([]);
|
||||
const album_info = ref([]);
|
||||
const album_artists = ref([]);
|
||||
const filters = ref([]);
|
||||
|
||||
const magic_flag = ref(false);
|
||||
@@ -61,5 +63,5 @@ export default {
|
||||
search_artists,
|
||||
album_song_list,
|
||||
album_info,
|
||||
album_artists
|
||||
album_artists,
|
||||
};
|
||||
|
||||
+1
-1
@@ -13,4 +13,4 @@ const emitter = mitt();
|
||||
const app = createApp(App);
|
||||
app.use(router);
|
||||
app.provide('emitter', emitter);
|
||||
app.mount('#app');
|
||||
app.mount('#app');
|
||||
|
||||
@@ -57,7 +57,6 @@ export default {
|
||||
if (state.album_artists.value.length == 0) {
|
||||
album.getAlbumArtists(title, album_artists).then((data) => {
|
||||
state.album_artists.value = data;
|
||||
console.log(state.album_artists.value)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<script>
|
||||
import Header from "@/components/PlaylistView/Header.vue";
|
||||
import SongList from "@/components/PlaylistView/SongList.vue";
|
||||
import SongList from "@/components/FolderView/SongList.vue";
|
||||
import FeaturedArtists from "@/components/PlaylistView/FeaturedArtists.vue";
|
||||
|
||||
export default {
|
||||
|
||||
Reference in New Issue
Block a user