refactor(front): [WIP] implement new layout for Album base page
This commit is contained in:
parent
4b167437c0
commit
be492901dc
|
@ -7,10 +7,12 @@ import { useI18n } from 'vue-i18n'
|
|||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { sum } from 'lodash-es'
|
||||
import { useStore } from '~/store'
|
||||
import { useQueue } from '~/composables/audio/queue'
|
||||
|
||||
import axios from 'axios'
|
||||
|
||||
import ArtistCreditLabel from '~/components/audio/ArtistCreditLabel.vue'
|
||||
import TrackFavoriteIcon from '~/components/favorites/TrackFavoriteIcon.vue'
|
||||
import PlayButton from '~/components/audio/PlayButton.vue'
|
||||
import TagsList from '~/components/tags/List.vue'
|
||||
import AlbumDropdown from './AlbumDropdown.vue'
|
||||
|
@ -18,6 +20,7 @@ import Layout from '~/components/ui/Layout.vue'
|
|||
import Spacer from '~/components/ui/Spacer.vue'
|
||||
import Loader from '~/components/ui/Loader.vue'
|
||||
import Section from '~/components/ui/Section.vue'
|
||||
import Button from '~/components/ui/Button.vue'
|
||||
|
||||
import useErrorHandler from '~/composables/useErrorHandler'
|
||||
import useLogger from '~/composables/useLogger'
|
||||
|
@ -58,10 +61,17 @@ const publicLibraries = computed(() => libraries.value?.filter(library => librar
|
|||
const logger = useLogger()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const labels = computed(() => ({
|
||||
title: t('components.library.AlbumBase.title')
|
||||
title: t('components.library.AlbumBase.title'),
|
||||
shuffle: t('components.audio.Player.label.shuffleQueue')
|
||||
}))
|
||||
|
||||
const {
|
||||
isShuffled,
|
||||
shuffle,
|
||||
} = useQueue()
|
||||
|
||||
const isLoading = ref(false)
|
||||
const fetchData = async () => {
|
||||
isLoading.value = true
|
||||
|
@ -146,7 +156,6 @@ const remove = async () => {
|
|||
v-title="labels.title"
|
||||
/>
|
||||
<template v-if="object">
|
||||
<!-- Image -->
|
||||
<Layout flex>
|
||||
<img
|
||||
v-if="object.cover && object.cover.urls.original"
|
||||
|
@ -176,19 +185,65 @@ const remove = async () => {
|
|||
/>
|
||||
<!-- Metadata: -->
|
||||
<div>
|
||||
<!-- EP -->
|
||||
·
|
||||
<!-- 2022 -->
|
||||
·
|
||||
<!-- 7 tracks -->
|
||||
<template v-if="object.release_date">
|
||||
{{ momentFormat(new Date(object.release_date ?? '1970-01-01'), 'Y') }}
|
||||
<i class="bi bi-dot" />
|
||||
</template>
|
||||
<template v-if="totalTracks > 0">
|
||||
<span v-if="isSerie">
|
||||
{{ t('components.library.AlbumBase.meta.episodes', totalTracks) }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ t('components.library.AlbumBase.meta.tracks', totalTracks) }}
|
||||
</span>
|
||||
</template>
|
||||
<i v-if="totalDuration > 0" class="bi bi-dot" />
|
||||
<human-duration
|
||||
v-if="totalDuration > 0"
|
||||
:duration="totalDuration"
|
||||
/>
|
||||
<i v-if="object.tags && object.tags.length > 0" class="bi bi-dot" />
|
||||
<!--TODO: License -->
|
||||
<TagsList
|
||||
v-if="object.tags && object.tags.length > 0"
|
||||
:tags="object.tags"
|
||||
/>
|
||||
</div>
|
||||
<Layout flex>
|
||||
<!-- Pause -->
|
||||
<!-- Shuffle -->
|
||||
<Spacer h grow />
|
||||
<!-- Herzchen -->
|
||||
<rendered-description
|
||||
v-if="object.description"
|
||||
:content="object.description"
|
||||
:can-update="false"
|
||||
/>
|
||||
</Layout>
|
||||
<Layout flex>
|
||||
<PlayButton
|
||||
class="vibrant"
|
||||
:tracks="object.tracks"
|
||||
:is-playable="object.is_playable"
|
||||
/>
|
||||
<Button
|
||||
primary
|
||||
icon="bi-shuffle"
|
||||
:disabled="object.tracks.length < 2"
|
||||
:aria-label="labels.shuffle"
|
||||
@click.prevent.stop="shuffle()"
|
||||
>
|
||||
{{ labels.shuffle }}
|
||||
</Button>
|
||||
<Spacer h grow />
|
||||
<TrackFavoriteIcon v-if="store.state.auth.authenticated" :album="object" />
|
||||
<!-- Button mit Pfeilchen -->
|
||||
<!-- OptionsButton / -->
|
||||
<album-dropdown
|
||||
:object="object"
|
||||
:public-libraries="publicLibraries"
|
||||
:is-loading="isLoading"
|
||||
:is-album="isAlbum"
|
||||
:is-serie="isSerie"
|
||||
:is-channel="isChannel"
|
||||
:artist-credit="artistCredit"
|
||||
@remove="remove"
|
||||
/>
|
||||
</Layout>
|
||||
</Layout>
|
||||
</Section>
|
||||
|
@ -202,224 +257,20 @@ const remove = async () => {
|
|||
<!-- 1 selected -->
|
||||
</Layout>
|
||||
|
||||
<!-- hier die einzelnen Tracks -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Reference: -->
|
||||
<section class="segment channel-serie">
|
||||
<Layout flex gap-64 style="align-content: stretch;">
|
||||
<div style="flex: 2;">
|
||||
<div
|
||||
v-if="isSerie"
|
||||
class="padded basic segment"
|
||||
>
|
||||
<div
|
||||
v-if="isSerie"
|
||||
class="ui two column grid"
|
||||
>
|
||||
<div class="column">
|
||||
<div class="large two-images">
|
||||
<img
|
||||
v-if="object.cover && object.cover.urls.original"
|
||||
v-lazy="store.getters['instance/absoluteUrl'](object.cover.urls.medium_square_crop)"
|
||||
alt=""
|
||||
class="channel-image"
|
||||
>
|
||||
<img
|
||||
v-else
|
||||
alt=""
|
||||
class="channel-image"
|
||||
src="../../assets/audio/default-cover.png"
|
||||
>
|
||||
<img
|
||||
v-if="object.cover && object.cover.urls.original"
|
||||
v-lazy="store.getters['instance/absoluteUrl'](object.cover.urls.medium_square_crop)"
|
||||
alt=""
|
||||
class="channel-image"
|
||||
>
|
||||
<img
|
||||
v-else
|
||||
alt=""
|
||||
class="channel-image"
|
||||
src="../../assets/audio/default-cover.png"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui column right aligned">
|
||||
<TagsList
|
||||
v-if="object.tags && object.tags.length > 0"
|
||||
:tags="object.tags"
|
||||
/>
|
||||
<div class="ui small hidden divider" />
|
||||
<human-duration
|
||||
v-if="totalDuration > 0"
|
||||
:duration="totalDuration"
|
||||
/>
|
||||
<template v-if="totalTracks > 0">
|
||||
<div class="ui hidden very small divider" />
|
||||
<span v-if="isSerie">
|
||||
{{ t('components.library.AlbumBase.meta.episodes', totalTracks) }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ t('components.library.AlbumBase.meta.tracks', totalTracks) }}
|
||||
</span>
|
||||
</template>
|
||||
<PlayButton
|
||||
class="vibrant"
|
||||
:tracks="object.tracks"
|
||||
:is-playable="object.is_playable"
|
||||
/>
|
||||
<div class="ui hidden horizontal divider" />
|
||||
<album-dropdown
|
||||
:object="object"
|
||||
:public-libraries="publicLibraries"
|
||||
:is-loading="isLoading"
|
||||
:is-album="isAlbum"
|
||||
:is-serie="isSerie"
|
||||
:is-channel="isChannel"
|
||||
:artist-credit="artistCredit"
|
||||
@remove="remove"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<header>
|
||||
<h2
|
||||
class="ui header"
|
||||
:title="object.title"
|
||||
>
|
||||
{{ object.title }}
|
||||
</h2>
|
||||
<artist-credit-label
|
||||
v-if="artistCredit"
|
||||
:artist-credit="artistCredit"
|
||||
/>
|
||||
</header>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="ui center aligned text padded basic segment"
|
||||
>
|
||||
<img
|
||||
v-if="object.cover && object.cover.urls.original"
|
||||
v-lazy="store.getters['instance/absoluteUrl'](object.cover.urls.medium_square_crop)"
|
||||
alt=""
|
||||
class="channel-image"
|
||||
>
|
||||
<img
|
||||
v-else
|
||||
alt=""
|
||||
class="channel-image"
|
||||
src="../../assets/audio/default-cover.png"
|
||||
>
|
||||
<div class="ui hidden divider" />
|
||||
<header>
|
||||
<h2
|
||||
class="ui header"
|
||||
:title="object.title"
|
||||
>
|
||||
{{ object.title }}
|
||||
</h2>
|
||||
<artist-credit-label
|
||||
v-if="artistCredit"
|
||||
:artist-credit="artistCredit"
|
||||
/>
|
||||
</header>
|
||||
<Spacer :size="16"/>
|
||||
<div
|
||||
v-if="object.release_date || (totalTracks > 0)"
|
||||
class="ui small hidden divider"
|
||||
/>
|
||||
<template v-if="object.release_date">
|
||||
{{ momentFormat(new Date(object.release_date ?? '1970-01-01'), 'Y') }}
|
||||
<span class="middle middledot symbol" />
|
||||
</template>
|
||||
<template v-if="totalTracks > 0">
|
||||
<span v-if="isSerie">
|
||||
{{ t('components.library.AlbumBase.meta.episodes', totalTracks) }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ t('components.library.AlbumBase.meta.tracks', totalTracks) }}
|
||||
</span>
|
||||
<span class="middle middledot symbol" />
|
||||
</template>
|
||||
<human-duration
|
||||
v-if="totalDuration > 0"
|
||||
:duration="totalDuration"
|
||||
/>
|
||||
<div class="ui small hidden divider" />
|
||||
<play-button
|
||||
class="vibrant"
|
||||
:album="object"
|
||||
:is-playable="object.is_playable"
|
||||
/>
|
||||
<div class="ui horizontal hidden divider" />
|
||||
<album-dropdown
|
||||
:object="object"
|
||||
:public-libraries="publicLibraries"
|
||||
:is-loading="isLoading"
|
||||
:is-album="isAlbum"
|
||||
:is-serie="isSerie"
|
||||
:is-channel="isChannel"
|
||||
:artist-credit="artistCredit"
|
||||
@remove="remove"
|
||||
/>
|
||||
<div v-if="(object.tags && object.tags.length > 0) || object.description || store.state.auth.authenticated && object.is_local">
|
||||
<div class="ui small hidden divider" />
|
||||
<div class="ui divider" />
|
||||
<div class="ui small hidden divider" />
|
||||
<template v-if="object.tags && object.tags.length > 0">
|
||||
<TagsList :tags="object.tags" />
|
||||
<div class="ui small hidden divider" />
|
||||
</template>
|
||||
<rendered-description
|
||||
v-if="object.description"
|
||||
:content="object.description"
|
||||
:can-update="false"
|
||||
/>
|
||||
<router-link
|
||||
v-else-if="store.state.auth.authenticated && object.is_local"
|
||||
:to="{name: 'library.albums.edit', params: {id: object.id }}"
|
||||
>
|
||||
<i class="pencil icon" />
|
||||
{{ t('components.library.AlbumBase.link.addDescription') }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="isSerie">
|
||||
<div class="ui hidden divider" />
|
||||
<rendered-description
|
||||
v-if="object.description"
|
||||
:content="object.description"
|
||||
:can-update="false"
|
||||
/>
|
||||
<router-link
|
||||
v-else-if="store.state.auth.authenticated && object.is_local"
|
||||
:to="{name: 'library.albums.edit', params: {id: object.id }}"
|
||||
>
|
||||
<i class="pencil icon" />
|
||||
{{ t('components.library.AlbumBase.link.addDescription') }}
|
||||
</router-link>
|
||||
</template>
|
||||
</div>
|
||||
<div style="flex 1;">
|
||||
<router-view
|
||||
v-if="object"
|
||||
:key="route.fullPath"
|
||||
:paginate-by="paginateBy"
|
||||
:total-tracks="totalTracks"
|
||||
:is-serie="isSerie"
|
||||
:artist-credit="artistCredit"
|
||||
:object="object"
|
||||
:is-loading-tracks="isLoadingTracks"
|
||||
object-type="album"
|
||||
@libraries-loaded="libraries = $event"
|
||||
/>
|
||||
</div>
|
||||
</Layout>
|
||||
</section>
|
||||
<div style="flex 1;">
|
||||
<router-view
|
||||
v-if="object"
|
||||
:key="route.fullPath"
|
||||
:paginate-by="paginateBy"
|
||||
:total-tracks="totalTracks"
|
||||
:is-serie="isSerie"
|
||||
:artist-credit="artistCredit"
|
||||
:object="object"
|
||||
:is-loading-tracks="isLoadingTracks"
|
||||
object-type="album"
|
||||
@libraries-loaded="libraries = $event"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Layout>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue