From 35a8446f8b0edc92938550a89ee8dbadcf194b64 Mon Sep 17 00:00:00 2001 From: geoffrey45 Date: Mon, 12 Dec 2022 13:18:05 +0300 Subject: [PATCH] setup artist discography page --- src/components/AlbumView/ArtistAlbums.vue | 19 +++++- src/components/AlbumView/Header.vue | 7 ++- .../nav/Titles/ArtistDiscographyTitle.vue | 27 +++++--- src/components/shared/ArtistName.vue | 2 +- src/composables/enums.ts | 10 ++- src/composables/fetch/artists.ts | 4 +- src/stores/pages/artistDiscog.ts | 63 +++++++++++++++++++ src/views/AlbumView/index.vue | 19 ++++-- src/views/AlbumsGrid.vue | 35 ++++++----- src/views/ArtistView/Main.vue | 48 +++++++++++--- 10 files changed, 189 insertions(+), 45 deletions(-) create mode 100644 src/stores/pages/artistDiscog.ts diff --git a/src/components/AlbumView/ArtistAlbums.vue b/src/components/AlbumView/ArtistAlbums.vue index b79b1e02..c7c63809 100644 --- a/src/components/AlbumView/ArtistAlbums.vue +++ b/src/components/AlbumView/ArtistAlbums.vue @@ -2,8 +2,16 @@

{{ title }} - - + SEE ALL @@ -21,9 +29,16 @@ import { Album } from "@/interfaces"; import { maxAbumCards } from "@/stores/content-width"; import { Routes } from "@/router/routes"; +import { discographyAlbumTypes } from "@/composables/enums"; +import useArtistDiscographyStore from "@/stores/pages/artistDiscog"; + +const store = useArtistDiscographyStore(); + defineProps<{ title: string; + artisthash: string; albums: Album[]; + albumType: discographyAlbumTypes; }>(); diff --git a/src/components/AlbumView/Header.vue b/src/components/AlbumView/Header.vue index e06fb74b..a92c646d 100644 --- a/src/components/AlbumView/Header.vue +++ b/src/components/AlbumView/Header.vue @@ -81,9 +81,10 @@ import { albumHeaderSmall } from "@/stores/content-width"; import useNavStore from "@/stores/nav"; import useAlbumStore from "@/stores/pages/album"; import { formatSeconds, useVisibility } from "@/utils"; -import { isLight } from "../../composables/colors/album"; -import { playSources, Routes } from "../../composables/enums"; -import { Album } from "../../interfaces"; +import { isLight } from "@/composables/colors/album"; +import { playSources } from "@/composables/enums"; +import { Album } from "@/interfaces"; +import { Routes } from "@/router/routes"; import PlayBtnRect from "../shared/PlayBtnRect.vue"; diff --git a/src/components/nav/Titles/ArtistDiscographyTitle.vue b/src/components/nav/Titles/ArtistDiscographyTitle.vue index 0bd9cd2a..78b03437 100644 --- a/src/components/nav/Titles/ArtistDiscographyTitle.vue +++ b/src/components/nav/Titles/ArtistDiscographyTitle.vue @@ -2,20 +2,23 @@

Creedence Clearwater Revival

- -
+
-
Albums
-
Singles & EPs
-
Appearances
+
+ {{ a }} +
@@ -29,6 +32,11 @@ import { onClickOutside } from "@vueuse/core"; import ArrowSvg from "@/assets/icons/expand.svg"; import GridSvg from "@/assets/icons/grid.svg"; import { Ref, ref } from "vue"; +import { discographyAlbumTypes as albums } from "@/composables/enums"; + +import useArtistDiscogStore from "@/stores/pages/artistDiscog"; + +const store = useArtistDiscogStore(); const showDropDown = ref(false); const dropOptionsRef: Ref = ref(); @@ -37,6 +45,11 @@ function hideDropDown() { showDropDown.value = false; } +function switchView(album: albums) { + store.setAlbums(album); + hideDropDown(); +} + onClickOutside(dropOptionsRef, (e) => { e.stopImmediatePropagation(); hideDropDown(); diff --git a/src/components/shared/ArtistName.vue b/src/components/shared/ArtistName.vue index 0d0f7a4b..86043b38 100644 --- a/src/components/shared/ArtistName.vue +++ b/src/components/shared/ArtistName.vue @@ -34,7 +34,7 @@ import { Routes } from "@/router/routes"; const props = defineProps<{ artists: Artist[] | null; - albumartists: Artist[] | null; + albumartists: Artist[] | string | null; small?: boolean; smaller?: boolean; }>(); diff --git a/src/composables/enums.ts b/src/composables/enums.ts index 679f38c8..b6542c7e 100644 --- a/src/composables/enums.ts +++ b/src/composables/enums.ts @@ -20,7 +20,7 @@ export enum FromOptions { album = "album", search = "search", artist = "artist", - albumCard = "albumCard" + albumCard = "albumCard", } export enum ContextSrc { @@ -43,3 +43,11 @@ export enum contextChildrenShowMode { click = "click", hover = "hover", } + +export enum discographyAlbumTypes { + all = "All", + albums = "Albums", + singles = "Singles", + eps = "EPs", + appearances = "Appearances", +} diff --git a/src/composables/fetch/artists.ts b/src/composables/fetch/artists.ts index cb827705..f473b290 100644 --- a/src/composables/fetch/artists.ts +++ b/src/composables/fetch/artists.ts @@ -20,7 +20,7 @@ const getArtistData = async (hash: string, limit: number = 5) => { return data as ArtistData; }; -const getArtistAlbums = async (hash: string, limit = 6) => { +const getArtistAlbums = async (hash: string, all = false, limit = 6) => { interface ArtistAlbums { albums: Album[]; eps: Album[]; @@ -30,7 +30,7 @@ const getArtistAlbums = async (hash: string, limit = 6) => { const { data, error } = await useAxios({ get: true, - url: paths.api.artist + `/${hash}/albums?limit=${limit}`, + url: paths.api.artist + `/${hash}/albums?limit=${limit}&all=${all}`, }); if (error) { diff --git a/src/stores/pages/artistDiscog.ts b/src/stores/pages/artistDiscog.ts new file mode 100644 index 00000000..b81daa74 --- /dev/null +++ b/src/stores/pages/artistDiscog.ts @@ -0,0 +1,63 @@ +import { defineStore } from "pinia"; +import { discographyAlbumTypes } from "@/composables/enums"; +import { Album } from "@/interfaces"; +import { getArtistAlbums } from "@/composables/fetch/artists"; + +export default defineStore("artistDiscography", { + state: () => ({ + artist: "", + page: discographyAlbumTypes.all, + + toShow: [], + + albums: [], + eps: [], + singles: [], + appearances: [], + }), + actions: { + setAlbums(page: discographyAlbumTypes) { + switch (page) { + case discographyAlbumTypes.albums: + this.toShow = this.albums; + break; + case discographyAlbumTypes.eps: + this.toShow = this.eps; + break; + case discographyAlbumTypes.singles: + this.toShow = this.singles; + break; + case discographyAlbumTypes.appearances: + this.toShow = this.appearances; + break; + default: + this.toShow = this.albums.concat( + this.eps, + this.singles, + this.appearances + ); + } + }, + setPage(page: discographyAlbumTypes) { + this.page = page; + }, + fetchAlbums(artisthash: string) { + getArtistAlbums(artisthash, true) + .then((data) => { + this.albums = data.albums; + this.eps = data.eps; + this.singles = data.singles; + this.appearances = data.appearances; + }) + .then(() => this.setAlbums(this.page)); + }, + resetAlbums() { + this.albums = []; + this.eps = []; + this.singles = []; + this.appearances = []; + + this.toShow = []; + }, + }, +}); diff --git a/src/views/AlbumView/index.vue b/src/views/AlbumView/index.vue index 7a10ab95..315375ed 100644 --- a/src/views/AlbumView/index.vue +++ b/src/views/AlbumView/index.vue @@ -37,6 +37,7 @@ import Header from "@/components/AlbumView/Header.vue"; import SongItem from "@/components/shared/SongItem.vue"; import { isSmall } from "@/stores/content-width"; +import { discographyAlbumTypes } from "@/composables/enums"; const album = useAlbumStore(); const queue = useQueueStore(); @@ -80,14 +81,22 @@ function getSongItems() { } function getArtistAlbumComponents(): ScrollerItem[] { - return album.albumArtists.map((artist) => { - const artist_name = album.info.albumartists.find( - (a) => a.artisthash === artist.artisthash - )?.name; + return album.albumArtists.map((ar) => { + const artist = album.info.albumartists.find( + (a) => a.artisthash === ar.artisthash + ); + const artistname = artist?.name; + const artisthash = artist?.artisthash; + return { id: Math.random().toString(), component: ArtistAlbums, - props: { title: `More from ${artist_name}`, albums: artist.albums }, + props: { + artisthash, + albums: ar.albums, + title: `More from ${artistname}`, + albumType: discographyAlbumTypes.all, + }, size: 20 * 16, }; }); diff --git a/src/views/AlbumsGrid.vue b/src/views/AlbumsGrid.vue index b71dd955..6d0a3f94 100644 --- a/src/views/AlbumsGrid.vue +++ b/src/views/AlbumsGrid.vue @@ -1,43 +1,46 @@ diff --git a/src/views/ArtistView/Main.vue b/src/views/ArtistView/Main.vue index 33c1155d..37c169ff 100644 --- a/src/views/ArtistView/Main.vue +++ b/src/views/ArtistView/Main.vue @@ -22,7 +22,6 @@ :is="item.component" v-bind="item.props" > - @@ -38,10 +37,12 @@ import useArtistPageStore from "@/stores/pages/artist"; import ArtistAlbums from "@/components/AlbumView/ArtistAlbums.vue"; import ArtistAlbumsFetcher from "@/components/ArtistView/ArtistAlbumsFetcher.vue"; import { computed } from "vue"; -import { onBeforeRouteLeave, onBeforeRouteUpdate } from "vue-router"; +import { onBeforeRouteLeave, onBeforeRouteUpdate, useRoute } from "vue-router"; import { Album } from "@/interfaces"; +import { discographyAlbumTypes } from "@/composables/enums"; const store = useArtistPageStore(); +const route = useRoute(); interface ScrollerItem { id: string | number; @@ -64,13 +65,41 @@ const artist_albums_fetcher: ScrollerItem = { component: ArtistAlbumsFetcher, }; -function createAbumComponent(title: string, albums: Album[]) { +enum AlbumType { + ALBUMS = "Albums", + EPS = "EPs", + SINGLES = "Singles", + APPEARANCES = "Appearances", +} + +function createAbumComponent(title: AlbumType, albums: Album[]) { + let albumType = null; + + switch (title) { + case AlbumType.ALBUMS: + albumType = discographyAlbumTypes.albums; + break; + case AlbumType.EPS: + albumType = discographyAlbumTypes.eps; + break; + case AlbumType.SINGLES: + albumType = discographyAlbumTypes.singles; + break; + case AlbumType.APPEARANCES: + albumType = discographyAlbumTypes.appearances; + break; + + default: + break; + } return { id: title, component: ArtistAlbums, props: { - title, + albumType, albums, + title, + artisthash: route.params.hash, }, }; } @@ -85,22 +114,25 @@ const scrollerItems = computed(() => { components = [...components, artist_albums_fetcher]; if (store.albums.length > 0) { - const albums = createAbumComponent("Albums", store.albums); + const albums = createAbumComponent(AlbumType.ALBUMS, store.albums); components.push(albums); } if (store.eps.length > 0) { - const eps = createAbumComponent("EPs", store.eps); + const eps = createAbumComponent(AlbumType.EPS, store.eps); components.push(eps); } if (store.singles.length > 0) { - const singles = createAbumComponent("Singles", store.singles); + const singles = createAbumComponent(AlbumType.SINGLES, store.singles); components.push(singles); } if (store.appearances.length > 0) { - const appearances = createAbumComponent("Appearances", store.appearances); + const appearances = createAbumComponent( + AlbumType.APPEARANCES, + store.appearances + ); components.push(appearances); }