diff --git a/src/components/AlbumView/GenreBanner.vue b/src/components/AlbumView/GenreBanner.vue index 1d02ff1..679ba3a 100644 --- a/src/components/AlbumView/GenreBanner.vue +++ b/src/components/AlbumView/GenreBanner.vue @@ -25,10 +25,10 @@ import { isLight } from "@/composables/colors/album"; const album = useAlbumStore(); -onMounted(() => { +onMounted(async () => { // onMounted, fetch data to be used in the component below this one. const album = useAlbumStore(); - album.fetchArtistAlbums(); + await album.fetchArtistAlbums(); }); diff --git a/src/components/AlbumView/Header.vue b/src/components/AlbumView/Header.vue index 8ade5d0..0bdc66a 100644 --- a/src/components/AlbumView/Header.vue +++ b/src/components/AlbumView/Header.vue @@ -40,11 +40,10 @@
-  • {{ album.date }} • {{ album.count }} + />  • {{ album.date }} • {{ album.count }} {{ album.count === 1 ? "Track" : "Tracks" }} • {{ formatSeconds(album.duration, true) }}
@@ -57,7 +56,7 @@ v-for="a in album.albumartists" :to="{ name: Routes.artist, - params: { hash: a.hash }, + params: { hash: a.artisthash }, }" >
{{ albumartists }}
- {{ - artist - }} +
+ + diff --git a/src/components/shared/SongItem.vue b/src/components/shared/SongItem.vue index 66a3995..559a6d4 100644 --- a/src/components/shared/SongItem.vue +++ b/src/components/shared/SongItem.vue @@ -131,6 +131,7 @@ function showMenu(e: MouseEvent) { .song-album { max-width: max-content; + cursor: pointer !important; &:hover { diff --git a/src/composables/fetch/artists.ts b/src/composables/fetch/artists.ts index d6442c2..2c263bc 100644 --- a/src/composables/fetch/artists.ts +++ b/src/composables/fetch/artists.ts @@ -5,22 +5,32 @@ import { Artist, Track, Album } from "@/interfaces"; const getArtistData = async (hash: string) => { interface ArtistData { artist: Artist; - albums: Album[]; tracks: Track[]; } const { data, error } = await useAxios({ get: true, - url: paths.api.artist + `/${hash}?limit=6`, + url: paths.api.artist + `/${hash}`, }); if (error) { console.error(error); } - console.log(data); - return data as ArtistData; }; -export { getArtistData }; +const getArtistAlbums = async (hash: string, limit = 6) => { + const { data, error } = await useAxios({ + get: true, + url: paths.api.artist + `/${hash}/albums?limit=${limit}`, + }); + + if (error) { + console.error(error); + } + + return data.albums as Album[]; +}; + +export { getArtistData, getArtistAlbums }; diff --git a/src/composables/mediaNotification.ts b/src/composables/mediaNotification.ts index 6fa4762..70285af 100644 --- a/src/composables/mediaNotification.ts +++ b/src/composables/mediaNotification.ts @@ -6,11 +6,16 @@ export default () => { if ("mediaSession" in navigator) { const queue = useQueueStore(); const { currenttrack: track } = queue; - const url = paths.images.thumb.large + + if (track === undefined) { + return; + } + + const url = paths.images.thumb.large; navigator.mediaSession.metadata = new window.MediaMetadata({ title: track.title, - artist: track.artist.join(", "), + artist: track.artist.map((a) => a.name).join(", "), artwork: [ { src: url + track.image, diff --git a/src/config.ts b/src/config.ts index a7a6f68..baa0d92 100644 --- a/src/config.ts +++ b/src/config.ts @@ -20,7 +20,6 @@ const imageRoutes = { large: "/t/", small: "/t/s/", }, - // artist: "/a/", artist: { large: "/a/", small: "/a/s/", diff --git a/src/interfaces.ts b/src/interfaces.ts index 89f2386..c3df293 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -9,7 +9,7 @@ export interface Track extends AlbumDisc { id: string; title: string; album?: string; - artist: string[]; + artist: Artist[]; albumartist: string; albumhash?: string; folder?: string; @@ -37,11 +37,7 @@ export interface Folder { export interface Album { albumid: string; title: string; - albumartists: { - name: string; - hash: string; - image: string; - }[]; + albumartists: Artist[]; count: number; duration: number; date: string; diff --git a/src/stores/content-width.ts b/src/stores/content-width.ts index e31e3a4..f8e4c52 100644 --- a/src/stores/content-width.ts +++ b/src/stores/content-width.ts @@ -21,5 +21,17 @@ const isMedium = computed(() => { const albumHeaderSmall = computed(() => { return content_width.value <= brk.album_header_small; }); +const album_card_with = 10 * 16; -export { content_width, window_width, isSmall, isMedium, albumHeaderSmall }; +const maxAbumCards = computed(() => { + return Math.floor(content_width.value / album_card_with); +}); + +export { + content_width, + window_width, + isSmall, + isMedium, + albumHeaderSmall, + maxAbumCards, +}; diff --git a/src/stores/pages/album.ts b/src/stores/pages/album.ts index be8e50a..97531d4 100644 --- a/src/stores/pages/album.ts +++ b/src/stores/pages/album.ts @@ -4,11 +4,11 @@ import { ComputedRef } from "vue"; import { AlbumDisc } from "./../../interfaces"; import { FuseTrackOptions } from "@/composables/enums"; -import { content_width } from "@/stores/content-width"; +import { maxAbumCards } from "@/stores/content-width"; import { - getAlbumsFromArtist, - getAlbumTracks + getAlbumsFromArtist, + getAlbumTracks, } from "../../composables/fetch/album"; import { Album, Artist, FuseResult, Track } from "../../interfaces"; import { useNotifStore } from "../notification"; @@ -27,11 +27,11 @@ function sortByTrackNumber(tracks: Track[]) { }); } -function albumHasNoDiscs(album: Album) { - if (album.is_single) return true; +// function albumHasNoDiscs(album: Album) { +// if (album.is_single) return true; - return false; -} +// return false; +// } /** * @@ -68,13 +68,12 @@ export default defineStore("album", { }, async fetchArtistAlbums() { const albumartists = this.info.albumartists; - const cardWidth = 10 * 16; - const visible_cards = Math.floor(content_width.value / cardWidth); - const albumartisthashes = albumartists.map((artist) => artist.hash); + + const albumartisthashes = albumartists.map((artist) => artist.artisthash); this.albumArtists = await getAlbumsFromArtist( albumartisthashes.join(), - visible_cards, + maxAbumCards.value, this.info.albumhash ); }, diff --git a/src/stores/pages/artist.ts b/src/stores/pages/artist.ts index eb7916e..40246a0 100644 --- a/src/stores/pages/artist.ts +++ b/src/stores/pages/artist.ts @@ -1,7 +1,8 @@ import { defineStore } from "pinia"; import { Artist, Album, Track } from "@/interfaces"; -import { getArtistData } from "@/composables/fetch/artists"; +import { getArtistData, getArtistAlbums } from "@/composables/fetch/artists"; +import { maxAbumCards } from "@/stores/content-width"; export default defineStore("artistPage", { state: () => ({ @@ -11,11 +12,23 @@ export default defineStore("artistPage", { }), actions: { async getData(hash: string) { - const { artist, albums, tracks } = await getArtistData(hash); + const { artist, tracks } = await getArtistData(hash); this.info = artist; this.tracks = tracks; - this.albums = albums; + }, + async getArtistAlbums() { + const albums = await getArtistAlbums( + this.info.artisthash, + maxAbumCards.value + ); + + if (albums.length > 0) { + this.albums = albums; + } + }, + resetAlbums() { + this.albums = []; }, }, }); diff --git a/src/views/AlbumView/index.vue b/src/views/AlbumView/index.vue index a82714f..0be277a 100644 --- a/src/views/AlbumView/index.vue +++ b/src/views/AlbumView/index.vue @@ -86,7 +86,7 @@ function getSongItems() { function getArtistAlbumComponents(): ScrollerItem[] { return album.albumArtists.map((artist) => { const artist_name = album.info.albumartists.find( - (a) => a.hash === artist.artisthash + (a) => a.artisthash === artist.artisthash )?.name; return { id: Math.random().toString(), @@ -121,7 +121,7 @@ function playFromAlbum(index: number) { queue.play(index); } -onBeforeRouteUpdate(async (to: RouteLocationNormalized) => { +onBeforeRouteUpdate(async (to) => { await album.fetchTracksAndArtists(to.params.hash.toString()).then(() => { album.resetQuery(); album.resetAlbumArtists(); diff --git a/src/views/ArtistView/ArtistAlbumsFetcher.vue b/src/views/ArtistView/ArtistAlbumsFetcher.vue new file mode 100644 index 0000000..1ef949a --- /dev/null +++ b/src/views/ArtistView/ArtistAlbumsFetcher.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/views/ArtistView/Main.vue b/src/views/ArtistView/Main.vue index 4df0b16..52fe102 100644 --- a/src/views/ArtistView/Main.vue +++ b/src/views/ArtistView/Main.vue @@ -34,14 +34,13 @@ import { isMedium, isSmall } from "@/stores/content-width"; import Header from "@/components/ArtistView/Header.vue"; import TopTracks from "@/components/ArtistView/TopTracks.vue"; -// import Albums from "@/components/ArtistView/Albums.vue"; import useArtistPageStore from "@/stores/pages/artist"; import ArtistAlbums from "@/components/AlbumView/ArtistAlbums.vue"; - +import ArtistAlbumsFetcher from "./ArtistAlbumsFetcher.vue"; import { computed } from "vue"; import { onBeforeRouteUpdate } from "vue-router"; -const artistStore = useArtistPageStore(); +const store = useArtistPageStore(); interface ScrollerItem { id: string | number; @@ -59,18 +58,25 @@ const top_tracks: ScrollerItem = { component: TopTracks, }; +const artist_albums_fetcher: ScrollerItem = { + id: "artist-albums-fetcher", + component: ArtistAlbumsFetcher, +}; + const scrollerItems = computed(() => { let components = [header]; - if (artistStore.tracks.length > 0) { + if (store.tracks.length > 0) { components.push(top_tracks); } - if (artistStore.albums.length > 0) { + components = [...components, artist_albums_fetcher]; + + if (store.albums.length > 0) { const artistAlbums: ScrollerItem = { id: "artist-albums", component: ArtistAlbums, - props: { title: "Albums", albums: artistStore.albums }, + props: { title: "Albums", albums: store.albums }, }; components.push(artistAlbums); @@ -79,8 +85,9 @@ const scrollerItems = computed(() => { return components; }); -onBeforeRouteUpdate((to, from, next) => { - artistStore.getData(to.params.hash as string); +onBeforeRouteUpdate(async (to) => { + + await store.getData(to.params.hash as string); });