mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-07-29 14:12:21 +00:00
handle favoriting in album page
+ fix fetching artist albums + create favoriteHandler composable
This commit is contained in:
parent
a0cf95024c
commit
d250928573
@ -50,7 +50,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<PlayBtnRect :source="playSources.album" :store="useAlbumStore" />
|
<PlayBtnRect :source="playSources.album" :store="useAlbumStore" />
|
||||||
<HeartSvg />
|
<HeartSvg :state="is_fav" @handleFav="handleFav"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -85,14 +85,15 @@ import useNavStore from "@/stores/nav";
|
|||||||
import useAlbumStore from "@/stores/pages/album";
|
import useAlbumStore from "@/stores/pages/album";
|
||||||
import { formatSeconds, useVisibility } from "@/utils";
|
import { formatSeconds, useVisibility } from "@/utils";
|
||||||
import { isLight } from "@/composables/colors/album";
|
import { isLight } from "@/composables/colors/album";
|
||||||
import { playSources } from "@/composables/enums";
|
import { favType, playSources } from "@/composables/enums";
|
||||||
import { Album } from "@/interfaces";
|
import { Album } from "@/interfaces";
|
||||||
import { Routes } from "@/router/routes";
|
import { Routes } from "@/router/routes";
|
||||||
import HeartSvg from "../shared/HeartSvg.vue";
|
import HeartSvg from "../shared/HeartSvg.vue";
|
||||||
|
|
||||||
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
||||||
|
import favoriteHandler from "@/composables/favoriteHandler";
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
album: Album;
|
album: Album;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@ -115,6 +116,12 @@ function handleVisibilityState(state: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useVisibility(albumheaderthing, handleVisibilityState);
|
useVisibility(albumheaderthing, handleVisibilityState);
|
||||||
|
|
||||||
|
const is_fav = ref(props.album.is_favorite);
|
||||||
|
|
||||||
|
function handleFav() {
|
||||||
|
favoriteHandler(is_fav, favType.album, props.album.albumhash);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -173,7 +180,6 @@ useVisibility(albumheaderthing, handleVisibilityState);
|
|||||||
|
|
||||||
.art {
|
.art {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
// align-items: center;
|
|
||||||
gap: $small;
|
gap: $small;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
|
@ -51,38 +51,23 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
import { paths } from "@/config";
|
||||||
import useArtistPageStore from "@/stores/pages/artist";
|
import useArtistPageStore from "@/stores/pages/artist";
|
||||||
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 { favType, playSources } from "@/composables/enums";
|
import { favType, playSources } from "@/composables/enums";
|
||||||
|
import favoriteHandler from "@/composables/favoriteHandler";
|
||||||
|
|
||||||
|
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
||||||
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);
|
const is_fav = ref(artist.info.is_favorite);
|
||||||
|
|
||||||
async function handleFav() {
|
function handleFav() {
|
||||||
if (is_fav.value) {
|
favoriteHandler(is_fav, favType.artist, artist.info.artisthash);
|
||||||
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>
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="heart-button circular" @click="emit('handleFav')">
|
<button
|
||||||
|
class="heart-button circular"
|
||||||
|
@click="emit('handleFav')"
|
||||||
|
:class="{
|
||||||
|
is_fav: state,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<HeartFillSvg v-if="state" />
|
<HeartFillSvg v-if="state" />
|
||||||
<HeartSvg v-else />
|
<HeartSvg v-else />
|
||||||
</button>
|
</button>
|
||||||
@ -19,15 +25,18 @@ const emit = defineEmits<{
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
$bg: rgb(250, 33, 33);
|
||||||
|
|
||||||
.heart-button {
|
.heart-button {
|
||||||
$bg: rgb(255, 184, 184);
|
|
||||||
background: $bg;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
gap: $smaller;
|
gap: $smaller;
|
||||||
|
border: solid 1px $bg;
|
||||||
|
background: transparent;
|
||||||
|
color: rgb(250, 33, 33);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $bg;
|
background: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
{{ index }}
|
{{ index }}
|
||||||
</div>
|
</div>
|
||||||
<div class="heart-icon">
|
<div class="heart-icon">
|
||||||
<HeartFillSvg v-if="fav" />
|
<HeartFillSvg v-if="is_fav" />
|
||||||
<HeartSvg v-else />
|
<HeartSvg v-else />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -83,10 +83,10 @@ import OptionSvg from "@/assets/icons/more.svg";
|
|||||||
import ArtistName from "./ArtistName.vue";
|
import ArtistName from "./ArtistName.vue";
|
||||||
|
|
||||||
import useQueueStore from "@/stores/queue";
|
import useQueueStore from "@/stores/queue";
|
||||||
import { addFavorite, removeFavorite } from "@/composables/fetch/favorite";
|
|
||||||
import { favType } from "@/composables/enums";
|
import { favType } from "@/composables/enums";
|
||||||
|
|
||||||
import MasterFlag from "./MasterFlag.vue";
|
import MasterFlag from "./MasterFlag.vue";
|
||||||
|
import favoriteHandler from "@/composables/favoriteHandler";
|
||||||
|
|
||||||
const imguri = paths.images.thumb.small;
|
const imguri = paths.images.thumb.small;
|
||||||
const context_menu_showing = ref(false);
|
const context_menu_showing = ref(false);
|
||||||
@ -120,24 +120,10 @@ function isCurrentPlaying() {
|
|||||||
return isCurrent() && queue.playing;
|
return isCurrent() && queue.playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fav = ref(props.track.is_favorite);
|
const is_fav = ref(props.track.is_favorite);
|
||||||
|
|
||||||
async function addToFav(trackhash: string) {
|
function addToFav(trackhash: string) {
|
||||||
if (fav.value) {
|
favoriteHandler(is_fav, favType.track, trackhash);
|
||||||
const removed = await removeFavorite(favType.track, trackhash);
|
|
||||||
|
|
||||||
if (removed) {
|
|
||||||
fav.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const added = await addFavorite(favType.track, trackhash);
|
|
||||||
|
|
||||||
if (added) {
|
|
||||||
fav.value = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
31
src/composables/favoriteHandler.ts
Normal file
31
src/composables/favoriteHandler.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { Ref } from "vue";
|
||||||
|
import { favType } from "./enums";
|
||||||
|
import { addFavorite, removeFavorite } from "./fetch/favorite";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the favorite state of an item.
|
||||||
|
* @param flag The ref to track the is_favorite state
|
||||||
|
* @param type The type of item
|
||||||
|
* @param itemhash The hash of the item
|
||||||
|
*/
|
||||||
|
export default async function favoriteHandler(
|
||||||
|
flag: Ref<boolean | undefined>,
|
||||||
|
type: favType,
|
||||||
|
itemhash: string
|
||||||
|
) {
|
||||||
|
if (flag.value) {
|
||||||
|
const removed = await removeFavorite(type, itemhash);
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
flag.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const added = await addFavorite(type, itemhash);
|
||||||
|
|
||||||
|
if (added) {
|
||||||
|
flag.value = true;
|
||||||
|
}
|
||||||
|
}
|
@ -54,6 +54,7 @@ export interface Album {
|
|||||||
is_soundtrack: boolean;
|
is_soundtrack: boolean;
|
||||||
is_single: boolean;
|
is_single: boolean;
|
||||||
is_EP: boolean;
|
is_EP: boolean;
|
||||||
|
is_favorite: boolean;
|
||||||
genres: string[];
|
genres: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ export default defineStore("artistDiscography", {
|
|||||||
this.page = page;
|
this.page = page;
|
||||||
},
|
},
|
||||||
fetchAlbums(artisthash: string) {
|
fetchAlbums(artisthash: string) {
|
||||||
getArtistAlbums(artisthash, true)
|
getArtistAlbums(artisthash, 0, true)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.albums = data.albums;
|
this.albums = data.albums;
|
||||||
this.eps = data.eps;
|
this.eps = data.eps;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user