mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
add album header info
This commit is contained in:
@@ -350,3 +350,24 @@ def getAlbums():
|
|||||||
albums.append(al_obj)
|
albums.append(al_obj)
|
||||||
|
|
||||||
return {'albums': albums}
|
return {'albums': albums}
|
||||||
|
|
||||||
|
@bp.route('/albums/<album>')
|
||||||
|
def getAlbumSongs(album: str):
|
||||||
|
album = urllib.parse.unquote(album)
|
||||||
|
songs = all_songs_instance.find_songs_by_album(album)
|
||||||
|
songs_array = convert_to_json(songs)
|
||||||
|
|
||||||
|
for song in songs_array:
|
||||||
|
song['artists'] = song['artists'].split(', ')
|
||||||
|
song['filepath'] = song['filepath'].replace(home_dir, '')
|
||||||
|
song['image'] = img_path + song['image']
|
||||||
|
|
||||||
|
album_obj = {
|
||||||
|
"name": album,
|
||||||
|
"count": len(songs_array),
|
||||||
|
"duration": sum(song['length'] for song in songs_array),
|
||||||
|
"image": songs_array[0]['image'],
|
||||||
|
"artist": songs_array[0]['album_artist']
|
||||||
|
# "date": songs_array[0]['date']
|
||||||
|
}
|
||||||
|
return {'songs': songs_array, 'info': album_obj}
|
||||||
+1
-1
@@ -53,7 +53,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const collapsed = ref(false);
|
const collapsed = ref(true);
|
||||||
|
|
||||||
perks.readQueue();
|
perks.readQueue();
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="a-header rounded">
|
<div class="a-header rounded">
|
||||||
<div class="art rounded"></div>
|
<div id="header-blur"></div>
|
||||||
|
<div
|
||||||
|
class="art rounded"
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url("${album_info.image}")`,
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="title">{{ album.title }}</div>
|
<div class="title">{{ album_info.name }}</div>
|
||||||
<div class="artist">{{ album.artist }}</div>
|
<div class="artist">{{ album_info.artist }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<div class="stats">
|
<div class="stats">
|
||||||
{{ album.count }} Tracks • {{ album.duration }} • {{ album.date }}
|
{{ album_info.count }} Tracks • {{ album_info.duration }} • 2021
|
||||||
</div>
|
</div>
|
||||||
<div class="play rounded">
|
<div class="play rounded">
|
||||||
<div class="icon"></div>
|
<div class="icon"></div>
|
||||||
@@ -17,57 +23,79 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="most-played">
|
||||||
|
<div class="image rounded"></div>
|
||||||
|
<div>
|
||||||
|
<div class="title">Girl Of My Dreams</div>
|
||||||
|
<div class="artist">Juice Wrld, Suga [BTS]</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref } from "@vue/reactivity";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
props: ["album_info"],
|
||||||
const album = ref({
|
setup() {},
|
||||||
title: "Fighting Demons",
|
|
||||||
artist: "Juice Wrld",
|
|
||||||
count: 17,
|
|
||||||
duration: "54 min",
|
|
||||||
date: 2021,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
album,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.a-header {
|
#header-blur {
|
||||||
height: 14rem;
|
height: 100%;
|
||||||
background: rgb(0, 0, 0);
|
width: 100%;
|
||||||
background: #355c7d; /* fallback for old browsers */
|
position: absolute;
|
||||||
background: -webkit-linear-gradient(
|
z-index: -1;
|
||||||
to right,
|
left: 0;
|
||||||
#c06c84,
|
backdrop-filter: blur(20px);
|
||||||
#6c5b7b,
|
}
|
||||||
#355c7d
|
|
||||||
); /* Chrome 10-25, Safari 5.1-6 */
|
|
||||||
background: linear-gradient(
|
|
||||||
to right,
|
|
||||||
#c06c84,
|
|
||||||
#6c5b7b,
|
|
||||||
#355c7d
|
|
||||||
); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
|
||||||
|
|
||||||
background-position: 50% 10%;
|
.a-header {
|
||||||
|
position: relative;
|
||||||
|
height: 14rem;
|
||||||
|
background: #232526;
|
||||||
|
background: -webkit-linear-gradient(to right, #414345, #232526);
|
||||||
|
background: linear-gradient(to right, #050107, #00090e);
|
||||||
|
|
||||||
|
backdrop-filter: blur(0px);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 1rem 0 1rem;
|
padding: 0 1rem 0 1rem;
|
||||||
|
|
||||||
|
.most-played {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 0 0 $small;
|
||||||
|
background-color: rgb(24, 24, 24);
|
||||||
|
border-radius: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
width: 25rem;
|
||||||
|
height: 5rem;
|
||||||
|
|
||||||
|
.image {
|
||||||
|
width: 4rem;
|
||||||
|
height: 4rem;
|
||||||
|
background-image: url(../../assets/images/jw.jpeg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-left: $small;
|
||||||
|
margin-bottom: $small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artist {
|
||||||
|
font-size: small;
|
||||||
|
margin-left: $small;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.art {
|
.art {
|
||||||
width: 12rem;
|
width: 12rem;
|
||||||
height: 12rem;
|
height: 12rem;
|
||||||
background: no-repeat center/cover url(../../assets/images/jw.jpeg);
|
background: no-repeat center/cover url(../../assets/images/null.webp);
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +132,7 @@ export default {
|
|||||||
width: 6rem;
|
width: 6rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: rgb(33, 145, 61);
|
background: $blue;
|
||||||
padding: $small;
|
padding: $small;
|
||||||
margin: $small 0;
|
margin: $small 0;
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td :style="{ width: songTitleWidth + 'px' }">
|
<td :style="{ width: songTitleWidth + 'px' }">
|
||||||
<div class="ellip">{{ song.album }}</div>
|
<router-link
|
||||||
|
class="ellip"
|
||||||
|
:to="{ name: 'AlbumView', params: { album: song.album } }"
|
||||||
|
>{{ song.album }}</router-link
|
||||||
|
>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
:style="{ width: songTitleWidth + 'px' }"
|
:style="{ width: songTitleWidth + 'px' }"
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
let base_uri = "http://127.0.0.1:9876";
|
||||||
|
|
||||||
|
const getAlbum = async (name) => {
|
||||||
|
const res = await fetch(base_uri + "/albums/" + name);
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
const message = `An error has occured: ${res.status}`;
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getAlbum;
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
import { ref } from "@vue/reactivity";
|
let base_uri = "http://127.0.0.1:9876";
|
||||||
|
|
||||||
let folders_uri = "http://127.0.0.1:9876";
|
|
||||||
|
|
||||||
const getData = async (path) => {
|
const getData = async (path) => {
|
||||||
let url;
|
let url;
|
||||||
const songs = ref(null);
|
|
||||||
const folders = ref(null);
|
|
||||||
|
|
||||||
const encoded_path = encodeURIComponent(path.replaceAll("/", "|"));
|
const encoded_path = encodeURIComponent(path.replaceAll("/", "|"));
|
||||||
url = url = `${folders_uri}/f/${encoded_path}`;
|
url = url = `${base_uri}/f/${encoded_path}`;
|
||||||
|
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
|
|
||||||
@@ -19,8 +15,8 @@ const getData = async (path) => {
|
|||||||
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
songs.value = data.files;
|
const songs = data.files;
|
||||||
folders.value = data.folders;
|
const folders = data.folders;
|
||||||
|
|
||||||
return { songs, folders };
|
return { songs, folders };
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ const routes = [
|
|||||||
component: AlbumsExplorer,
|
component: AlbumsExplorer,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/albums/:id",
|
path: "/albums/:album",
|
||||||
name: "AlbumView",
|
name: "AlbumView",
|
||||||
component: AlbumView,
|
component: AlbumView,
|
||||||
},
|
},
|
||||||
|
|||||||
+24
-4
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="al-view rounded">
|
<div class="al-view rounded">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<Header />
|
<Header :album_info="album_info"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="separator" id="av-sep"></div>
|
<div class="separator" id="av-sep"></div>
|
||||||
<div>
|
<div>
|
||||||
<SongList />
|
<SongList :album_songs="album_songs"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="separator" id="av-sep"></div>
|
<div class="separator" id="av-sep"></div>
|
||||||
<FeaturedArtists />
|
<FeaturedArtists />
|
||||||
@@ -17,7 +17,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import { useRoute } from 'vue-router'
|
import { useRoute } from "vue-router";
|
||||||
|
import { onMounted, ref } from "@vue/runtime-core";
|
||||||
|
|
||||||
import Header from "../components/AlbumView/Header.vue";
|
import Header from "../components/AlbumView/Header.vue";
|
||||||
import AlbumBio from "../components/AlbumView/AlbumBio.vue";
|
import AlbumBio from "../components/AlbumView/AlbumBio.vue";
|
||||||
@@ -26,6 +27,8 @@ import FromTheSameArtist from "../components/AlbumView/FromTheSameArtist.vue";
|
|||||||
import SongList from "../components/PlaylistView/SongList.vue";
|
import SongList from "../components/PlaylistView/SongList.vue";
|
||||||
import FeaturedArtists from "../components/PlaylistView/FeaturedArtists.vue";
|
import FeaturedArtists from "../components/PlaylistView/FeaturedArtists.vue";
|
||||||
|
|
||||||
|
import getAlbum from "../composables/getAlbum.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Header,
|
Header,
|
||||||
@@ -34,7 +37,24 @@ export default {
|
|||||||
SongList,
|
SongList,
|
||||||
FeaturedArtists,
|
FeaturedArtists,
|
||||||
},
|
},
|
||||||
setup() {},
|
setup() {
|
||||||
|
const route = useRoute();
|
||||||
|
const album_name = route.params.album;
|
||||||
|
const album_songs = ref([]);
|
||||||
|
const album_info = ref({});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getAlbum(album_name).then((data) => {
|
||||||
|
album_songs.value = data.songs;
|
||||||
|
album_info.value = data.info;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
album_songs,
|
||||||
|
album_info,
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ export default {
|
|||||||
|
|
||||||
const songs = ref([]);
|
const songs = ref([]);
|
||||||
const folders = ref([]);
|
const folders = ref([]);
|
||||||
const last_page = ref([]);
|
|
||||||
const last_song_id = ref(null);
|
|
||||||
|
|
||||||
const scrollable = ref(null);
|
const scrollable = ref(null);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
@@ -45,14 +43,9 @@ export default {
|
|||||||
getData(path, last_id).then((data) => {
|
getData(path, last_id).then((data) => {
|
||||||
scrollable.value.scrollTop = 0;
|
scrollable.value.scrollTop = 0;
|
||||||
|
|
||||||
songs.value = data.songs.value;
|
songs.value = data.songs;
|
||||||
last_page.value = songs.value;
|
folders.value = data.folders;
|
||||||
|
|
||||||
if (songs.value.length) {
|
|
||||||
last_song_id.value = songs.value.slice(-1)[0]._id.$oid;
|
|
||||||
}
|
|
||||||
|
|
||||||
folders.value = data.folders.value;
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user