Improved mobile artist carousels

This commit is contained in:
lucast committed 2026-10-06 04:00:14 +02:00
1 parent f202f07585
commit 1fce02ad84
4 files changed
+89 -3

No files matched your search

+14 -1
View File
@@ -4,13 +4,14 @@ import type { Album } from "@/utils/types"
type AlbumProps = Omit<Omit<Album, "genre">, "artists"> & { type AlbumProps = Omit<Omit<Album, "genre">, "artists"> & {
artists: Array<Omit<Artist, "file">> artists: Array<Omit<Artist, "file">>
genre?: Genre genre?: Genre
carousel?: boolean
} }
const props = defineProps<AlbumProps>() const props = defineProps<AlbumProps>()
</script> </script>
<template> <template>
<article class="card"> <article class="card" :class="{ carousel: props.carousel }">
<NuxtLink :to="`/album/${props._id}`"> <NuxtLink :to="`/album/${props._id}`">
<NuxtImg <NuxtImg
:src="props.file" :src="props.file"
@@ -48,4 +49,16 @@ const props = defineProps<AlbumProps>()
} }
} }
} }
@media (max-width: 767px) {
.card.carousel {
min-width: 0;
max-width: none;
flex: 0 0 calc(45.455% - 9.091px);
& > a > img {
width: 100%;
}
}
}
</style> </style>
+1
View File
@@ -49,6 +49,7 @@ onMounted(async () => {
:file="GET_FILE(album.file)" :file="GET_FILE(album.file)"
:artists="album.artists" :artists="album.artists"
:_id="album._id" :_id="album._id"
carousel
/> />
</Slider> </Slider>
</template> </template>
+13
View File
@@ -126,4 +126,17 @@ onMounted(() => {
.right { .right {
right: -48px; right: -48px;
} }
@media (max-width: 767px) {
.left,
.right {
display: none;
}
.slider {
-webkit-overflow-scrolling: touch;
overscroll-behavior-x: contain;
scroll-padding-inline: 0.25rem;
}
}
</style> </style>
+61 -2
View File
@@ -44,12 +44,15 @@ useHead({ title: computed(() => artistData.value ? `${artistData.value.name} - A
<template> <template>
<section class="info" v-if="artistData"> <section class="info" v-if="artistData">
<div class="artist-art">
<NuxtImg <NuxtImg
class="artist-image"
:src="GET_FILE(artistData.file)" :src="GET_FILE(artistData.file)"
width="300" width="300"
height="300" height="300"
placeholder placeholder
/> />
</div>
<div class="details"> <div class="details">
<h1>{{ artistData.name }}</h1> <h1>{{ artistData.name }}</h1>
@@ -57,14 +60,18 @@ useHead({ title: computed(() => artistData.value ? `${artistData.value.name} - A
<div class="buttons"> <div class="buttons">
<Button <Button
icon-name="lucide:play" icon-name="lucide:play"
:aria-label="`Play ${artistData.name}`"
@click="() => playAlbum(tracks)" @click="() => playAlbum(tracks)"
>Play</Button
> >
<span class="button-label">Play</span>
</Button>
<Button <Button
icon-name="lucide:shuffle" icon-name="lucide:shuffle"
:aria-label="`Shuffle ${artistData.name}`"
@click="() => playShuffledAlbum(tracks)" @click="() => playShuffledAlbum(tracks)"
>Shuffle</Button
> >
<span class="button-label">Shuffle</span>
</Button>
</div> </div>
</div> </div>
</section> </section>
@@ -97,6 +104,7 @@ useHead({ title: computed(() => artistData.value ? `${artistData.value.name} - A
:file="GET_FILE(album.file)" :file="GET_FILE(album.file)"
:artists="album.artists" :artists="album.artists"
:_id="album._id" :_id="album._id"
carousel
/> />
</Slider> </Slider>
</template> </template>
@@ -158,4 +166,55 @@ $gap: 12px;
} }
} }
} }
@media (max-width: 767px) {
.info {
flex-direction: column;
align-items: stretch;
gap: 0.25rem;
}
.artist-art {
padding: 0.5rem;
}
.artist-image {
width: 100%;
height: auto;
}
.info .details {
align-items: center;
padding-top: 0;
text-align: center;
h1 {
margin-top: 0;
margin-bottom: 0;
}
.buttons {
margin-top: 0.375rem;
gap: 0.75rem;
}
}
.details .buttons :deep(.button) {
padding: 0.75rem;
border-radius: 50%;
}
.details .buttons :deep(.icon-wrapper) {
font-size: 1.5rem;
}
.details .buttons :deep(.button-label) {
display: none;
}
.tracks {
flex-basis: 100%;
min-width: 0;
}
}
</style> </style>