refactor(front): Use section on explore

This commit is contained in:
ArneBo 2025-02-05 00:41:06 +01:00
parent 8dde1f7906
commit 2562f5b1ab
3 changed files with 95 additions and 99 deletions

View File

@ -11,6 +11,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 Spacer from '~/components/ui/Spacer.vue' import Spacer from '~/components/ui/Spacer.vue'
import Loader from '~/components/ui/Loader.vue'
import useErrorHandler from '~/composables/useErrorHandler' import useErrorHandler from '~/composables/useErrorHandler'
@ -71,7 +72,7 @@ watch(
</script> </script>
<template> <template>
<h3 <h2
v-if="!!$slots.title" v-if="!!$slots.title"
class="ui header" class="ui header"
> >
@ -80,26 +81,23 @@ watch(
v-if="showCount" v-if="showCount"
class="ui tiny circular label" class="ui tiny circular label"
>{{ count }}</span> >{{ count }}</span>
</h3> </h2>
<slot /> <slot />
<inline-search-bar <inline-search-bar
v-if="search" v-if="search"
v-model="query" v-model="query"
@search="performSearch" @search="performSearch"
/> />
<div style="display:flex; flex-wrap:wrap; gap: 32px; margin-top:32px;"> <template v-if="!isLoading && albums.length >= 0">
<div <Layout flex>
v-if="isLoading" <Loader v-if="isLoading" />
class="ui inverted active dimmer" <album-card
> v-for="album in albums"
<div class="ui loader" /> :key="album.id"
</div> :album="album"
<album-card />
v-for="album in albums" </Layout>
:key="album.id" </template>
:album="album"
/>
</div>
<slot <slot
v-if="!isLoading && albums.length === 0" v-if="!isLoading && albums.length === 0"
name="empty-state" name="empty-state"

View File

@ -13,6 +13,7 @@ import useWebSocketHandler from '~/composables/useWebSocketHandler'
import Button from '~/components/ui/Button.vue' import Button from '~/components/ui/Button.vue'
import PlayButton from '~/components/audio/PlayButton.vue' import PlayButton from '~/components/audio/PlayButton.vue'
import TagsList from '~/components/tags/List.vue' import TagsList from '~/components/tags/List.vue'
import Section from '~/components/ui/Section.vue'
import Alert from '~/components/ui/Alert.vue' import Alert from '~/components/ui/Alert.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'
@ -38,7 +39,7 @@ const emit = defineEmits<Events>()
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
isActivity: true, isActivity: true,
showCount: false, showCount: false,
limit: 5, limit: 9,
itemClasses: '', itemClasses: '',
websocketHandlers: () => [] websocketHandlers: () => []
}) })
@ -108,13 +109,13 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
<template> <template>
<!-- TODO: Use activity.vue --> <!-- TODO: Use activity.vue -->
<div class="component-track-widget"> <div class="component-track-widget">
<h3 v-if="!!$slots.title"> <h2 v-if="!!$slots.title">
<slot name="title" /> <slot name="title" />
<span <span
v-if="showCount" v-if="showCount"
class="ui tiny circular label" class="ui tiny circular label"
>{{ count }}</span> >{{ count }}</span>
</h3> </h2>
<Alert <Alert
v-if="count === 0" v-if="count === 0"
blue blue
@ -124,8 +125,9 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
{{ t('components.audio.track.Widget.empty.noResults') }} {{ t('components.audio.track.Widget.empty.noResults') }}
<Loader v-if="isLoading" /> <Loader v-if="isLoading" />
</Alert> </Alert>
<div <Section
v-if="count > 0" v-if="count > 0"
medium-items
> >
<div class="funkwhale activity" <div class="funkwhale activity"
v-for="object in objects" v-for="object in objects"
@ -144,7 +146,7 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
alt="" alt=""
> >
<img <img
v-else-if="object.track.artist_credit && object.track.artist_credit.length > 0" v-else-if="object.track.artist_credit && object.track.artist_credit.length > 1"
v-lazy="getArtistCoverUrl(object.track.artist_credit)" v-lazy="getArtistCoverUrl(object.track.artist_credit)"
alt="" alt=""
> >
@ -163,52 +165,51 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
{{ object.track.title }} {{ object.track.title }}
</router-link> </router-link>
</div> </div>
<div <div
v-if="object.track.artist_credit" v-if="object.track.artist_credit"
class="funkwhale link artist" 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 } }"
> >
<span {{ ac.credit }}
v-for="ac in object.track.artist_credit" </router-link>
:key="ac.artist.id" <span v-if="ac.joinphrase">{{ ac.joinphrase }}</span>
> </span>
<router-link </div>
class="discrete link" <TagsList
:to="{ name: 'library.artists.detail', params: { id: ac.artist.id } }" label-classes="tiny"
> :truncate-size="20"
{{ ac.credit }} :limit="2"
</router-link> :show-more="false"
<span v-if="ac.joinphrase">{{ ac.joinphrase }}</span> :tags="object.track.tags"
</span> />
</div>
<TagsList
label-classes="tiny"
:truncate-size="20"
:limit="2"
:show-more="false"
:tags="object.track.tags"
/>
<div <div
v-if="isActivity" v-if="isActivity"
class="extra" class="extra"
> >
<router-link <router-link
class="funkwhale link user" class="funkwhale link user"
:to="{name: 'profile.overview', params: {username: object.actor.name}}" :to="{name: 'profile.overview', params: {username: object.actor.name}}"
> >
<span class="at symbol" />{{ object.actor.name }} <span class="at symbol" />{{ object.actor.name }}
</router-link> </router-link>
<span class="right floated"><human-date :date="object.creation_date" /></span> <span class="right floated"><human-date :date="object.creation_date" /></span>
</div>
</div>
<play-button
:account="object.actor"
:dropdown-only="true"
:track="object.track"
/>
</div> </div>
</div> </div>
<play-button
:account="object.actor"
:dropdown-only="true"
:track="object.track"
/>
</div> </div>
</Section>
<Loader v-if="isLoading" /> <Loader v-if="isLoading" />
<template v-if="nextPage"> <template v-if="nextPage">
<Spacer :size="16"/> <Spacer :size="16"/>
@ -219,6 +220,7 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
{{ t('components.audio.track.Widget.button.more') }} {{ t('components.audio.track.Widget.button.more') }}
</Button> </Button>
</template> </template>
</div>
</template> </template>

View File

@ -10,8 +10,9 @@ import ChannelsWidget from '~/components/audio/ChannelsWidget.vue'
import PlaylistWidget from '~/components/playlists/Widget.vue' import PlaylistWidget from '~/components/playlists/Widget.vue'
import TrackWidget from '~/components/audio/track/Widget.vue' import TrackWidget from '~/components/audio/track/Widget.vue'
import AlbumWidget from '~/components/album/Widget.vue' import AlbumWidget from '~/components/album/Widget.vue'
import Layout from '~/components/ui/Layout.vue'
import Header from '~/components/ui/Header.vue' import Header from '~/components/ui/Header.vue'
import Layout from '~/components/ui/Layout.vue'
import Section from '~/components/ui/Section.vue'
import useErrorHandler from '~/composables/useErrorHandler' import useErrorHandler from '~/composables/useErrorHandler'
import useLogger from '~/composables/useLogger' import useLogger from '~/composables/useLogger'
@ -62,7 +63,7 @@ fetchData()
</script> </script>
<template> <template>
<Layout main stack noGap <Layout main stack gap-64
:key="route?.name ?? undefined" :key="route?.name ?? undefined"
v-title="labels.title" v-title="labels.title"
> >
@ -76,42 +77,37 @@ fetchData()
</template> </template>
</playlist-widget> </playlist-widget>
<template v-if="scope === 'all'"> <Section
<h2>{{ t('components.library.Home.header.newChannels') }}</h2> v-if="scope === 'all'"
<channels-widget alignLeft
:show-modification-date="true" :h2="t('components.library.Home.header.newChannels')"
:limit="12" />
:filters="{ordering: '-creation_date', external: 'true'}" <channels-widget
:show-modification-date="true"
:limit="12"
:filters="{ordering: '-creation_date', external: 'true'}"
/>
<Section
alignLeft
:h2="t('components.library.Home.header.recentlyListened')"
/>
<track-widget
:url="'history/listenings/'"
:filters="{ scope, ordering: '-creation_date', ...qualityFilters}"
:websocket-handlers="['Listen']"
/> />
</template> <Section
alignLeft
<Section alignLeft> :h2="t('components.library.Home.header.recentlyFavorited')"
<track-widget />
:url="'history/listenings/'" <track-widget
:filters="{ scope, ordering: '-creation_date', ...qualityFilters}" :url="'favorites/tracks/'"
:websocket-handlers="['Listen']" :filters="{scope: scope, ordering: '-creation_date'}"
> />
<template #title> <Section
{{ t('components.library.Home.header.recentlyListened') }} alignLeft
</template> :h2="t('components.library.Home.header.recentlyAdded')"
</track-widget> />
</Section> <album-widget :filters="{scope: scope, playable: true, ordering: '-creation_date', ...qualityFilters}"/>
<Section>
<track-widget
:url="'favorites/tracks/'"
:filters="{scope: scope, ordering: '-creation_date'}"
>
<template #title>
{{ t('components.library.Home.header.recentlyFavorited') }}
</template>
</track-widget>
</Section>
<Section>
<album-widget :filters="{scope: scope, playable: true, ordering: '-creation_date', ...qualityFilters}">
<template #title>
{{ t('components.library.Home.header.recentlyAdded') }}
</template>
</album-widget>
</Section>
</Layout> </Layout>
</template> </template>