fix(front): consistent playbutton and style in all cards

This commit is contained in:
ArneBo 2025-01-27 13:47:48 +01:00
parent 275094bfee
commit 6f728036ec
8 changed files with 111 additions and 103 deletions

View File

@ -50,7 +50,15 @@ const imageUrl = computed(() => props.album.cover?.urls.original
:tags="album.tags"
:to="{name: 'library.albums.detail', params: {id: album.id}}"
>
<template
<template #topright>
<PlayButton
icon-only
:is-playable="album.is_playable"
:album="album"
/>
</template>
<template #default
v-for="ac in album.artist_credit"
:key="ac.artist.id"
>
@ -62,14 +70,6 @@ const imageUrl = computed(() => props.album.cover?.urls.original
<span>{{ ac.joinphrase }}</span>
</template>
<TagsList
label-classes="tiny"
:truncate-size="20"
:limit="2"
:show-more="false"
:tags="album.tags"
/>
<template #action>
<Spacer :size="8" />
<span v-if="album.release_date">
@ -90,30 +90,10 @@ const imageUrl = computed(() => props.album.cover?.urls.original
</Card>
</template>
<style scoped>
.funkwhale {
&.card.album-card {
--fw-border-radius: 12px;
--Card-width: 208px;
--Card-image-width: var(--Card-width);
--Card-padding: 16px;
> .card-image {
border-radius: 0 !important;
width: var(--Card-image-width);
margin: calc(-1 * var(--Card-padding)) calc(-1 * var(--Card-padding)) 0;
}
> .card-title {
font-size: 1rem;
text-align: left !important;
padding-top: 16px !important;
}
> .card-content {
padding-top: 0 !important;
text-align: left !important;
}
}
<style lang="scss" scoped>
.play-button {
position: absolute;
top: 214px;
right: 16px;
}
</style>

View File

@ -5,7 +5,6 @@ import { useStore } from '~/store'
import { useI18n } from 'vue-i18n'
import PlayButton from '~/components/audio/PlayButton.vue'
import TagsList from '~/components/tags/List.vue'
import Card from '~/components/ui/Card.vue'
import Spacer from '~/components/ui/Spacer.vue'
@ -47,10 +46,17 @@ const imageUrl = computed(() => cover.value?.urls.original
<Card
:title="artist.name"
:image="imageUrl"
class="card artist-card"
class="artist-card"
:tags="artist.tags"
:to="{name: 'library.artists.detail', params: {id: artist.id}}"
>
<template #topright>
<PlayButton
icon-only
:is-playable="artist.is_playable"
:artist="artist"
/>
</template>
<template #action>
<Spacer :size="8" />
@ -73,20 +79,10 @@ const imageUrl = computed(() => cover.value?.urls.original
</Card>
</template>
<style lang="scss">
.funkwhale {
.card.artist-card {
> .card-image {
border-radius: 50%;
width: 248px;
margin: 16px;
}
.play-button {
top: calc(var(--fw-card-width) - 44px - 8px) !important;
}
}
<style lang="scss" scoped>
.play-button {
position: absolute;
top: 214px;
right: 16px;
}
</style>

View File

@ -48,9 +48,18 @@ const updatedAgo = computed(() => moment(props.object.artist?.modification_date)
:title="object.artist?.name"
:image="imageUrl"
:tags="object.artist?.tags ?? []"
class="artist-card"
:to="{name: 'channels.detail', params: {id: urlId}}"
>
<div class="content">
<template #topright>
<PlayButton
icon-only
:is-playable="object.artist?.is_playable"
:artist="object.artist"
/>
</template>
<template #default>
<span
v-if="object.artist?.content_category === 'podcast'"
>
@ -61,7 +70,8 @@ const updatedAgo = computed(() => moment(props.object.artist?.modification_date)
<i class="bi bi-music-note-list" />
{{ t('components.audio.ChannelCard.meta.tracks', object.artist?.tracks_count ?? 0) }}
</span>
</div>
</template>
<template #action>
<time
:datetime="object.artist?.modification_date"
@ -80,3 +90,11 @@ const updatedAgo = computed(() => moment(props.object.artist?.modification_date)
</template>
</Card>
</template>
<style lang="scss" scoped>
.play-button {
position: absolute;
top: 214px;
right: 16px;
}
</style>

View File

@ -96,15 +96,6 @@ const labels = computed(() => ({
: t('components.audio.PlayButton.button.playTracks')
}))
const title = computed(() => {
if (props.track) {
return t('components.audio.PlayButton.title.unavailable')
}
return ''
})
const isOpen = ref(false)
</script>
@ -124,11 +115,10 @@ const isOpen = ref(false)
disabled: !playable,
primary: playable,
split: true,
splitIcon: 'bi-caret-down-fill',
splitTitle: title
splitIcon: 'bi-caret-down-fill'
}"
:aria-label="labels.replacePlay"
:class="[...buttonClasses]"
:class="[...buttonClasses, 'play-button']"
:isloading="isLoading"
:dropdownOnly="dropdownOnly"
@click.stop.prevent="replacePlay()"
@ -238,12 +228,12 @@ const isOpen = ref(false)
primary: playable,
}"
:aria-label="labels.replacePlay"
:class="[...buttonClasses]"
:class="[...buttonClasses, 'play-button']"
:isloading="isLoading"
:tiny="iconOnly && discrete"
:square="iconOnly"
:icon="!playing ? playIconClass : 'bi-pause-fill'"
:round="iconOnly"
:secondary="iconOnly && !discrete"
:primary="iconOnly && !discrete"
:ghost="discrete"
@click.stop.prevent="replacePlay()"
>

View File

@ -59,6 +59,14 @@ const goToPlaylist = () => {
:title="playlist.name"
:to="{ name: 'library.playlists.detail', params: { id: playlist.id } }"
>
<template #topright>
<PlayButton
iconOnly
:is-playable="playlist.is_playable"
:playlist="playlist"
/>
</template>
<template #image>
<div class="playlist-grid">
<img
@ -71,18 +79,11 @@ const goToPlaylist = () => {
</div>
</template>
<template #topright>
<PlayButton
iconOnly
:is-playable="playlist.is_playable"
:playlist="playlist"
/>
</template>
<template #default>
<div class="playlist-meta">
<ActorLink
:actor="playlist.actor"
discrete
/>
</div>
</template>
@ -91,6 +92,7 @@ const goToPlaylist = () => {
<div class="playlist-action">
<span>{{ t('components.playlists.Card.meta.tracks', playlist.tracks_count) }}</span>
<PlayButton
v-if="playlist.is_playable"
dropdown-only
:is-playable="playlist.is_playable"
:playlist="playlist"
@ -114,10 +116,15 @@ const goToPlaylist = () => {
}
}
.play-button {
position: absolute;
top: 214px;
right: 16px;
}
.playlist-meta {
display: flex;
align-items: center;
align-self: center;
}
.playlist-action {

View File

@ -85,6 +85,7 @@ const toggleRadio = () => {
:secondary="playOnly"
:round="playOnly"
icon="bi-play-fill"
:square="store.state.auth.authenticated && type === 'custom'"
@click="toggleRadio"
>
<div v-if="!playOnly">{{ buttonLabel }}</div>

View File

@ -42,14 +42,6 @@ const customRadioId = computed(() => props.customRadio?.id ?? null)
:title="radio.name"
:to="{name: 'library.radios.detail', params: {id: radio.id}}"
>
<div
class="description"
:class="{expanded: isDescriptionExpanded}"
@click="isDescriptionExpanded = !isDescriptionExpanded"
>
{{ radio.description }}
</div>
<Spacer />
<template #topright>
<radio-button
:type="type"
@ -58,13 +50,24 @@ const customRadioId = computed(() => props.customRadio?.id ?? null)
playOnly
/>
</template>
<div class="extra content">
<template #default>
<user-link
v-if="radio.user"
:user="radio.user"
discrete
class="left floated"
/>
</div>
<div
class="description"
:class="{expanded: isDescriptionExpanded}"
@click="isDescriptionExpanded = !isDescriptionExpanded"
>
{{ radio.description }}
</div>
<Spacer />
</template>
<template #action>
<Button
v-if="store.state.auth.authenticated && type === 'custom' && radio.user.id === store.state.auth.profile?.id"
@ -81,25 +84,30 @@ const customRadioId = computed(() => props.customRadio?.id ?? null)
large
:title="radio.name"
>
<div
class="description"
:class="{expanded: isDescriptionExpanded}"
@click="isDescriptionExpanded = !isDescriptionExpanded"
>
{{ radio.description }}
</div>
<Spacer />
<div class="extra content">
<user-link
v-if="radio.user"
:user="radio.user"
/>
<template #topright>
<radio-button
:type="type"
:custom-radio-id="customRadioId"
:object-id="objectId"
/>
</div>
</template>
<template #default>
<user-link
v-if="radio.user"
discrete
:user="radio.user"
/>
<div
class="description"
:class="{expanded: isDescriptionExpanded}"
@click="isDescriptionExpanded = !isDescriptionExpanded"
>
{{ radio.description }}
</div>
<Spacer />
</template>
<template #action>
<Button
v-if="store.state.auth.authenticated && type === 'custom' && radio.user.id === store.state.auth.profile?.id"
@ -112,3 +120,11 @@ const customRadioId = computed(() => props.customRadio?.id ?? null)
</template>
</Card>
</template>
<style lang="scss" scoped>
a.username {
display: flex;
align-self: center;
}
</style>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref, computed, useSlots, onMounted } from 'vue'
import { type ColorProps, type VariantProps, type DefaultProps, type RaisedProps, color } from '~/composables/color';
import { type ColorProps, type VariantProps, type DefaultProps, type RaisedProps, type PastelProps, color } from '~/composables/color';
import { type WidthProps, width } from '~/composables/width'
import { type AlignmentProps, align } from '~/composables/alignment'
@ -30,7 +30,7 @@ const props = defineProps<{
autofocus? : boolean
ariaPressed? : true
} & (ColorProps | DefaultProps)
} & (ColorProps | DefaultProps | PastelProps )
& VariantProps
& RaisedProps
& WidthProps