implement favoriting artists

This commit is contained in:
geoffrey45 2022-12-27 20:16:02 +03:00 committed by Mungai Njoroge
parent f7a054d569
commit a0cf95024c
8 changed files with 68 additions and 30 deletions

View File

@ -92,7 +92,7 @@ import HeartSvg from "../shared/HeartSvg.vue";
import PlayBtnRect from "../shared/PlayBtnRect.vue"; import PlayBtnRect from "../shared/PlayBtnRect.vue";
const props = defineProps<{ defineProps<{
album: Album; album: Album;
}>(); }>();

View File

@ -31,7 +31,7 @@
</section> </section>
<div class="buttons"> <div class="buttons">
<PlayBtnRect :source="playSources.artist" :store="useArtistPageStore" /> <PlayBtnRect :source="playSources.artist" :store="useArtistPageStore" />
<HeartSvg /> <HeartSvg @handleFav="handleFav" :state="is_fav" />
</div> </div>
</div> </div>
<div class="artist-img no-select"> <div class="artist-img no-select">
@ -56,10 +56,34 @@ import PlayBtnRect from "../shared/PlayBtnRect.vue";
import formatSeconds from "@/utils/useFormatSeconds"; import formatSeconds from "@/utils/useFormatSeconds";
import { isLight } from "@/composables/colors/album"; import { isLight } from "@/composables/colors/album";
import { paths } from "@/config"; import { paths } from "@/config";
import { playSources } from "@/composables/enums"; import { favType, playSources } from "@/composables/enums";
import HeartSvg from "@/components/shared/HeartSvg.vue"; import HeartSvg from "@/components/shared/HeartSvg.vue";
import { ref } from "vue";
import { addFavorite, removeFavorite } from "@/composables/fetch/favorite";
const artist = useArtistPageStore(); const artist = useArtistPageStore();
const is_fav = ref(artist.info.is_favorite);
async function handleFav() {
if (is_fav.value) {
const removed = await removeFavorite(
favType.artist,
artist.info.artisthash
);
if (removed) {
is_fav.value = false;
}
return;
}
const added = await addFavorite(favType.artist, artist.info.artisthash);
if (added) {
is_fav.value = true;
}
}
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -70,6 +70,8 @@ onUpdated(() => {
padding-right: $smaller; padding-right: $smaller;
width: fit-content; width: fit-content;
max-width: 100%; max-width: 100%;
overflow: scroll;
scrollbar-width: none;
.icon { .icon {
height: 2rem; height: 2rem;
@ -82,9 +84,6 @@ onUpdated(() => {
.paths { .paths {
display: flex; display: flex;
gap: $smaller; gap: $smaller;
overflow: hidden;
height: 100%;
scrollbar-width: none;
&::-webkit-scrollbar { &::-webkit-scrollbar {
display: none; display: none;
@ -100,10 +99,11 @@ onUpdated(() => {
} }
&::before { &::before {
content: "/"; content: "";
font-size: small; font-size: small;
margin-right: $smaller; margin-right: $smaller;
opacity: 0.25; color: $gray;
font-size: 1rem;
} }
&:first-child { &:first-child {

View File

@ -1,14 +1,26 @@
<template> <template>
<button class="heart-button circular"><HeartSvg /></button> <button class="heart-button circular" @click="emit('handleFav')">
<HeartFillSvg v-if="state" />
<HeartSvg v-else />
</button>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import HeartSvg from "@/assets/icons/heart.svg"; import HeartSvg from "@/assets/icons/heart.svg";
import HeartFillSvg from "@/assets/icons/heart.fill.svg";
defineProps<{
state: boolean | undefined;
}>();
const emit = defineEmits<{
(event: "handleFav"): void;
}>();
</script> </script>
<style lang="scss"> <style lang="scss">
.heart-button { .heart-button {
$bg: rgb(247, 149, 149); $bg: rgb(255, 184, 184);
background: $bg; background: $bg;
align-items: center; align-items: center;
padding: 0 1rem; padding: 0 1rem;

View File

@ -25,7 +25,7 @@ const getArtistData = async (hash: string, limit: number = 5) => {
return data as ArtistData; return data as ArtistData;
}; };
const getArtistAlbums = async (hash: string, all = false, limit = 6) => { const getArtistAlbums = async (hash: string, limit = 6, all = false) => {
interface ArtistAlbums { interface ArtistAlbums {
albums: Album[]; albums: Album[];
eps: Album[]; eps: Album[];

View File

@ -31,18 +31,6 @@ export default async (
const single_artist = track.artist.length === 1; const single_artist = track.artist.length === 1;
const single_album_artist = track.albumartist.length === 1; const single_album_artist = track.albumartist.length === 1;
let playlists = <Option[]>[];
const p = await getAllPlaylists();
playlists = p.map((playlist: Playlist) => {
return <Option>{
label: playlist.name,
action: () => {
addTrackToPlaylist(playlist, track);
},
};
});
const goToArtist = (artists: Artist[]) => { const goToArtist = (artists: Artist[]) => {
if (artists.length === 1) { if (artists.length === 1) {
return false; return false;
@ -62,7 +50,7 @@ export default async (
}); });
}; };
function addToPlaylist() { async function addToPlaylist() {
const new_playlist = <Option>{ const new_playlist = <Option>{
label: "New playlist", label: "New playlist",
action: () => { action: () => {
@ -70,12 +58,24 @@ export default async (
}, },
}; };
let playlists = <Option[]>[];
const p = await getAllPlaylists();
playlists = p.map((playlist: Playlist) => {
return <Option>{
label: playlist.name,
action: () => {
addTrackToPlaylist(playlist, track);
},
};
});
return [new_playlist, separator, ...playlists]; return [new_playlist, separator, ...playlists];
} }
const add_to_playlist: Option = { const add_to_playlist: Option = {
label: "Add to Playlist", label: "Add to Playlist",
children: addToPlaylist(), children: await addToPlaylist(),
icon: "plus", icon: "plus",
}; };
@ -99,7 +99,7 @@ export default async (
label: "Go to Folder", label: "Go to Folder",
action: () => { action: () => {
Router.push({ Router.push({
name: "FolderView", name: Routes.folder,
params: { path: track.folder }, params: { path: track.folder },
}); });
}, },
@ -142,7 +142,7 @@ export default async (
label: "Go to Album", label: "Go to Album",
action: () => { action: () => {
Router.push({ Router.push({
name: "AlbumView", name: Routes.album,
params: { hash: track.albumhash }, params: { hash: track.albumhash },
}); });
}, },
@ -170,12 +170,15 @@ export default async (
separator, separator,
go_to_album, go_to_album,
go_to_folder, go_to_folder,
// add_to_fav, separator,
go_to_artist, go_to_artist,
go_to_alb_artist, go_to_alb_artist,
// add_to_fav,
// separator, // separator,
// del_track, // del_track,
]; ];
return options; return options;
}; };
// TODO: Find a way to fetch playlists lazily. ie. When the "Add to playlist" option is triggered.

View File

@ -65,6 +65,7 @@ export interface Artist {
albumcount: number; albumcount: number;
duration: number; duration: number;
colors: string[]; colors: string[];
is_favorite?: boolean;
} }
export interface Option { export interface Option {

View File

@ -40,8 +40,6 @@ export default defineStore("context-menu", {
getBoundingClientRect: generateGetBoundingClientRect(e.x, e.y), getBoundingClientRect: generateGetBoundingClientRect(e.x, e.y),
} as VirtualElement; } as VirtualElement;
console.log(virtualElement.contextElement)
getContextOptions() getContextOptions()
.then((options) => { .then((options) => {
this.options = options; this.options = options;