style(front): Section components on explore

This commit is contained in:
ArneBo 2025-02-05 13:05:20 +01:00
parent bbc239b96c
commit 16c74b4078
5 changed files with 192 additions and 179 deletions

View File

@ -10,6 +10,7 @@ import axios from 'axios'
import AlbumCard from '~/components/album/Card.vue' import AlbumCard from '~/components/album/Card.vue'
import Button from '~/components/ui/Button.vue' import Button from '~/components/ui/Button.vue'
import Layout from '~/components/ui/Layout.vue'
import Spacer from '~/components/ui/Spacer.vue' import Spacer from '~/components/ui/Spacer.vue'
import Loader from '~/components/ui/Loader.vue' import Loader from '~/components/ui/Loader.vue'
@ -72,49 +73,50 @@ watch(
</script> </script>
<template> <template>
<h2 <div class="album-widget">
v-if="!!$slots.title" <h2
class="ui header" v-if="!!$slots.title"
>
<slot name="title" />
<span
v-if="showCount"
class="ui tiny circular label"
>{{ count }}</span>
</h2>
<slot />
<inline-search-bar
v-if="search"
v-model="query"
@search="performSearch"
/>
<template v-if="!isLoading && albums.length >= 0">
<Layout flex>
<Loader v-if="isLoading" />
<album-card
v-for="album in albums"
:key="album.id"
:album="album"
/>
</Layout>
</template>
<slot
v-if="!isLoading && albums.length === 0"
name="empty-state"
>
<empty-state
:refresh="true"
@refresh="fetchData"
/>
</slot>
<template v-if="nextPage">
<Spacer />
<Button
v-if="nextPage"
primary
@click="fetchData(nextPage)"
> >
{{ t('components.audio.album.Widget.button.more') }} <slot name="title" />
</Button> <span
</template> v-if="showCount"
class="ui tiny circular label"
>{{ count }}</span>
</h2>
<slot />
<inline-search-bar
v-if="search"
v-model="query"
@search="performSearch"
/>
<Loader v-if="isLoading" />
<template v-if="!isLoading && albums.length > 0">
<Layout flex>
<album-card
v-for="album in albums"
:key="album.id"
:album="album"
/>
</Layout>
</template>
<slot
v-if="!isLoading && albums.length === 0"
name="empty-state"
>
<empty-state
:refresh="true"
@refresh="fetchData"
/>
</slot>
<template v-if="nextPage">
<Spacer />
<Button
v-if="nextPage"
primary
@click="fetchData(nextPage)"
>
{{ t('components.audio.album.Widget.button.more') }}
</Button>
</template>
</div>
</template> </template>

View File

@ -61,7 +61,12 @@ fetchData()
</script> </script>
<template> <template>
<div> <div class="channel-widget">
<h2
v-if="!!$slots.title"
>
<slot name="title" />
</h2>
<slot /> <slot />
<Layout flex> <Layout flex>
<Loader v-if="isLoading" /> <Loader v-if="isLoading" />

View File

@ -109,117 +109,121 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
<template> <template>
<!-- TODO: Use activity.vue --> <!-- TODO: Use activity.vue -->
<h2 v-if="!!$slots.title"> <div class="track-widget">
<slot name="title" /> <h2 v-if="!!$slots.title">
<span <slot name="title" />
v-if="showCount" <span
class="ui tiny circular label" v-if="showCount"
>{{ count }}</span> class="ui tiny circular label"
</h2> >{{ count }}</span>
<Alert </h2>
v-if="count === 0" <Spacer :size="8" />
blue <Alert
style="text-align: center;" v-if="count === 0"
> blue
<i class="bi bi-music-note-list" /> style="text-align: center;"
{{ t('components.audio.track.Widget.empty.noResults') }}
<Loader v-if="isLoading" />
</Alert>
<template
v-if="count > 0"
medium-items
>
<div class="funkwhale activity"
v-for="object in objects"
:key="object.id"
:class="['item', itemClasses]"
> >
<div class="activity-image"> <i class="bi bi-music-note-list" />
<img {{ t('components.audio.track.Widget.empty.noResults') }}
v-if="object.track.album && object.track.album.cover" <Loader v-if="isLoading" />
v-lazy="store.getters['instance/absoluteUrl'](object.track.album.cover.urls.medium_square_crop)" </Alert>
alt="" <Section
> v-if="count > 0"
<img medium-items
v-else-if="object.track.cover" alignLeft
v-lazy="store.getters['instance/absoluteUrl'](object.track.cover.urls.medium_square_crop)" >
alt="" <div class="funkwhale activity"
> v-for="object in objects"
<img :key="object.id"
v-else-if="object.track.artist_credit && object.track.artist_credit.length > 1" :class="['item', itemClasses]"
v-lazy="getArtistCoverUrl(object.track.artist_credit)" >
alt="" <div class="activity-image">
> <img
<i v-if="object.track.album && object.track.album.cover"
v-else v-lazy="store.getters['instance/absoluteUrl'](object.track.album.cover.urls.medium_square_crop)"
class="bi bi-vinyl-fill" alt=""
/>
<!-- TODO: Add Playbutton overlay -->
</div>
<div class="activity-content">
<router-link
class="funkwhale link artist"
:to="{name: 'library.tracks.detail', params: {id: object.track.id}}"
> >
<Heading :h3="object.track.title" title /> <img
</router-link> v-else-if="object.track.cover"
<Spacer :size="2"/> v-lazy="store.getters['instance/absoluteUrl'](object.track.cover.urls.medium_square_crop)"
<div alt=""
v-if="object.track.artist_credit" >
class="funkwhale link artist" <img
> v-else-if="object.track.artist_credit && object.track.artist_credit.length > 1"
<span v-lazy="getArtistCoverUrl(object.track.artist_credit)"
v-for="ac in object.track.artist_credit" alt=""
:key="ac.artist.id" >
<i
v-else
class="bi bi-vinyl-fill"
/>
<!-- TODO: Add Playbutton overlay -->
</div>
<div class="activity-content">
<router-link
class="funkwhale link artist"
:to="{name: 'library.tracks.detail', params: {id: object.track.id}}"
>
<Heading :h3="object.track.title" title />
</router-link>
<Spacer :size="2"/>
<div
v-if="object.track.artist_credit"
class="funkwhale link artist"
>
<span
v-for="ac in object.track.artist_credit"
:key="ac.artist.id"
>
<router-link
class="discrete link"
:to="{ name: 'library.artists.detail', params: { id: ac.artist.id } }"
>
{{ ac.credit }}
</router-link>
<span v-if="ac.joinphrase">{{ ac.joinphrase }}</span>
</span>
</div>
<TagsList
label-classes="tiny"
:truncate-size="20"
:limit="2"
:show-more="false"
:tags="object.track.tags"
/>
<Spacer :size="4"/>
<div
v-if="isActivity"
class="extra"
> >
<router-link <router-link
class="discrete link" class="funkwhale link user"
:to="{ name: 'library.artists.detail', params: { id: ac.artist.id } }" :to="{name: 'profile.overview', params: {username: object.actor.name}}"
> >
{{ ac.credit }} <span class="at symbol" />{{ object.actor.name }}
</router-link> </router-link>
<span v-if="ac.joinphrase">{{ ac.joinphrase }}</span> <span class="right floated"><human-date :date="object.creation_date" /></span>
</span> </div>
</div> </div>
<TagsList <play-button
label-classes="tiny" :account="object.actor"
:truncate-size="20" :dropdown-only="true"
:limit="2" :track="object.track"
:show-more="false" square-small
:tags="object.track.tags"
/> />
<Spacer :size="4"/>
<div
v-if="isActivity"
class="extra"
>
<router-link
class="funkwhale link user"
:to="{name: 'profile.overview', params: {username: object.actor.name}}"
>
<span class="at symbol" />{{ object.actor.name }}
</router-link>
<span class="right floated"><human-date :date="object.creation_date" /></span>
</div>
</div> </div>
<play-button </Section>
:account="object.actor" <Loader v-if="isLoading" />
:dropdown-only="true" <template v-if="nextPage">
:track="object.track" <Spacer />
square-small <Button
/> primary
</div> @click="fetchData(nextPage as string)"
</template> >
<Loader v-if="isLoading" /> {{ t('components.audio.track.Widget.button.more') }}
<template v-if="nextPage"> </Button>
<Spacer :size="16"/> </template>
<Button </div>
primary
@click="fetchData(nextPage as string)"
>
{{ t('components.audio.track.Widget.button.more') }}
</Button>
</template>
</template> </template>

View File

@ -63,7 +63,7 @@ fetchData()
</script> </script>
<template> <template>
<Layout main stack gap-64 <Layout main stack
:key="route?.name ?? undefined" :key="route?.name ?? undefined"
v-title="labels.title" v-title="labels.title"
> >
@ -77,39 +77,40 @@ fetchData()
</template> </template>
</playlist-widget> </playlist-widget>
<Section
v-if="scope === 'all'"
alignLeft
:h2="t('components.library.Home.header.newChannels')"
/>
<channels-widget <channels-widget
v-if="scope === 'all'"
:show-modification-date="true" :show-modification-date="true"
:limit="12" :limit="12"
:filters="{ordering: '-creation_date', external: 'true'}" :filters="{ordering: '-creation_date', external: 'true'}"
/>
<Section
alignLeft
:h2="t('components.library.Home.header.recentlyListened')"
> >
<track-widget <template #title>
:url="'history/listenings/'" {{ t('components.library.Home.header.newChannels') }}
:filters="{ scope, ordering: '-creation_date', ...qualityFilters}" </template>
:websocket-handlers="['Listen']" </channels-widget>
/>
</Section> <track-widget
<Section :url="'history/listenings/'"
alignLeft :filters="{ scope, ordering: '-creation_date', ...qualityFilters}"
:h2="t('components.library.Home.header.recentlyFavorited')" :websocket-handlers="['Listen']"
> >
<track-widget <template #title>
:url="'favorites/tracks/'" {{ t('components.library.Home.header.recentlyListened') }}
:filters="{scope: scope, ordering: '-creation_date'}" </template>
/> </track-widget>
</Section>
<Section <track-widget
alignLeft :url="'favorites/tracks/'"
:h2="t('components.library.Home.header.recentlyAdded')" :filters="{scope: scope, ordering: '-creation_date'}"
/> >
<album-widget :filters="{scope: scope, playable: true, ordering: '-creation_date', ...qualityFilters}"/> <template #title>
{{ t('components.library.Home.header.recentlyFavorited') }}
</template>
</track-widget>
<album-widget :filters="{scope: scope, playable: true, ordering: '-creation_date', ...qualityFilters}">
<template #title>
{{ t('components.library.Home.header.recentlyAdded') }}
</template>
</album-widget>
</Layout> </Layout>
</template> </template>

View File

@ -58,7 +58,7 @@ watch(
</script> </script>
<template> <template>
<Layout stack> <div class="playlist-widget">
<h2 v-if="!!$slots.title"> <h2 v-if="!!$slots.title">
<slot name="title" /> <slot name="title" />
</h2> </h2>
@ -68,7 +68,7 @@ watch(
<Layout <Layout
v-else-if="objects.length > 0" v-else-if="objects.length > 0"
flex flex
style="gap: 16px; flex-wrap: wrap;" gap-16
> >
<PlaylistCard <PlaylistCard
v-for="playlist in objects" v-for="playlist in objects"
@ -97,6 +97,7 @@ watch(
</Alert> </Alert>
<template v-if="nextPage"> <template v-if="nextPage">
<Spacer />
<Button <Button
v-if="nextPage" v-if="nextPage"
primary primary
@ -105,5 +106,5 @@ watch(
{{ t('components.playlists.Widget.button.more') }} {{ t('components.playlists.Widget.button.more') }}
</Button> </Button>
</template> </template>
</Layout> </div>
</template> </template>