fix(front): playlist description and header component
This commit is contained in:
parent
d7402c29ab
commit
2b3831d4d3
|
@ -17,6 +17,7 @@ import HumanDate from '~/components/common/HumanDate.vue'
|
||||||
import TrackTable from '~/components/audio/track/Table.vue'
|
import TrackTable from '~/components/audio/track/Table.vue'
|
||||||
import PlayButton from '~/components/audio/PlayButton.vue'
|
import PlayButton from '~/components/audio/PlayButton.vue'
|
||||||
import Layout from '~/components/ui/Layout.vue'
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Header from '~/components/ui/Header.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'
|
||||||
import Button from '~/components/ui/Button.vue'
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
@ -125,6 +126,7 @@ const deletePlaylist = async () => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Layout
|
<Layout
|
||||||
|
v-title="playlist?.name"
|
||||||
stack
|
stack
|
||||||
main
|
main
|
||||||
>
|
>
|
||||||
|
@ -132,116 +134,92 @@ const deletePlaylist = async () => {
|
||||||
v-if="isLoading"
|
v-if="isLoading"
|
||||||
v-title="labels.playlist"
|
v-title="labels.playlist"
|
||||||
/>
|
/>
|
||||||
<Layout
|
<Header
|
||||||
v-if="!isLoading && playlist"
|
v-if="!isLoading && playlist"
|
||||||
v-title="playlist.name"
|
:h1="playlist.name"
|
||||||
flex
|
page-heading
|
||||||
>
|
>
|
||||||
<div class="playlist-grid">
|
<template #image>
|
||||||
<img
|
<div class="playlist-grid">
|
||||||
v-for="(url, idx) in images"
|
<img
|
||||||
:key="idx"
|
v-for="(url, idx) in images"
|
||||||
v-lazy="url"
|
:key="idx"
|
||||||
:alt="playlist.name"
|
v-lazy="url"
|
||||||
:style="{ backgroundColor: randomizedColors[idx % randomizedColors.length] }"
|
:alt="playlist.name"
|
||||||
>
|
:style="{ backgroundColor: randomizedColors[idx % randomizedColors.length] }"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="meta">
|
||||||
|
{{ playlist.tracks_count }}
|
||||||
|
{{ t('views.playlists.Detail.header.tracks') }}
|
||||||
|
<i class="bi bi-dot" />
|
||||||
|
<Duration :seconds="playlist.duration" />
|
||||||
</div>
|
</div>
|
||||||
<Layout
|
<Layout
|
||||||
stack
|
flex
|
||||||
style="flex: 1; gap: 8px;"
|
gap-8
|
||||||
>
|
>
|
||||||
<Spacer />
|
{{ t('views.playlists.Detail.meta.attribution') }}
|
||||||
<h1>{{ playlist.name }}</h1>
|
<ActorLink
|
||||||
<div class="meta">
|
:actor="playlist.actor"
|
||||||
{{ playlist.tracks_count }}
|
:avatar="false"
|
||||||
{{ t('views.playlists.Detail.header.tracks') }}
|
:discrete="true"
|
||||||
<i class="bi bi-dot" />
|
/>
|
||||||
<Duration :seconds="playlist.duration" />
|
<i class="bi bi-dot" />
|
||||||
</div>
|
{{ t('views.playlists.Detail.meta.updated') }}
|
||||||
<Layout
|
<HumanDate
|
||||||
flex
|
:date="playlist.modification_date"
|
||||||
gap-8
|
|
||||||
>
|
|
||||||
{{ t('views.playlists.Detail.meta.attribution') }}
|
|
||||||
<ActorLink
|
|
||||||
:actor="playlist.actor"
|
|
||||||
:avatar="false"
|
|
||||||
:discrete="true"
|
|
||||||
/>
|
|
||||||
<i class="bi bi-dot" />
|
|
||||||
{{ t('views.playlists.Detail.meta.updated') }}
|
|
||||||
<HumanDate
|
|
||||||
:date="playlist.modification_date"
|
|
||||||
/>
|
|
||||||
</Layout>
|
|
||||||
<RenderedDescription
|
|
||||||
:description="playlist.description"
|
|
||||||
:max-length="200"
|
|
||||||
:show-more="true"
|
|
||||||
/>
|
/>
|
||||||
<Layout
|
|
||||||
flex
|
|
||||||
class="header-buttons"
|
|
||||||
>
|
|
||||||
<PlayButton
|
|
||||||
split
|
|
||||||
:is-playable="playlist.is_playable"
|
|
||||||
:tracks="tracks"
|
|
||||||
>
|
|
||||||
{{ t('views.playlists.Detail.button.playAll') }}
|
|
||||||
</PlayButton>
|
|
||||||
<Button
|
|
||||||
v-if="playlist.tracks_count > 1"
|
|
||||||
primary
|
|
||||||
icon="bi-shuffle"
|
|
||||||
:aria-label="t('components.audio.Player.label.shuffleQueue')"
|
|
||||||
@click.prevent.stop="shuffle()"
|
|
||||||
>
|
|
||||||
{{ t('components.audio.Player.label.shuffleQueue') }}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
v-if="store.state.auth.profile && playlist.actor.full_username === store.state.auth.fullUsername"
|
|
||||||
secondary
|
|
||||||
icon="bi-pencil"
|
|
||||||
@click="edit = !edit"
|
|
||||||
>
|
|
||||||
<template v-if="edit">
|
|
||||||
{{ t('views.playlists.Detail.button.stopEdit') }}
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
{{ t('views.playlists.Detail.button.edit') }}
|
|
||||||
</template>
|
|
||||||
</Button>
|
|
||||||
<Spacer
|
|
||||||
h
|
|
||||||
grow
|
|
||||||
/>
|
|
||||||
<playlist-dropdown
|
|
||||||
:playlist="playlist"
|
|
||||||
@import="fetchData"
|
|
||||||
/>
|
|
||||||
</Layout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<Modal
|
<RenderedDescription
|
||||||
v-if="playlist.privacy_level === 'everyone' && playlist.is_playable"
|
:content="{ html: playlist.description }"
|
||||||
v-model="showEmbedModal"
|
:truncate-length="200"
|
||||||
title="t('views.playlists.Detail.modal.embed.header')"
|
:show-more="true"
|
||||||
|
/>
|
||||||
|
<Layout
|
||||||
|
flex
|
||||||
|
class="header-buttons"
|
||||||
>
|
>
|
||||||
<div class="scrolling content">
|
<PlayButton
|
||||||
<div class="description">
|
split
|
||||||
<embed-wizard
|
:is-playable="playlist.is_playable"
|
||||||
:id="playlist.id"
|
:tracks="tracks"
|
||||||
type="playlist"
|
>
|
||||||
/>
|
{{ t('views.playlists.Detail.button.playAll') }}
|
||||||
</div>
|
</PlayButton>
|
||||||
</div>
|
<Button
|
||||||
<template #actions>
|
v-if="playlist.tracks_count > 1"
|
||||||
<Button variant="outline">
|
primary
|
||||||
{{ t('views.playlists.Detail.button.cancel') }}
|
icon="bi-shuffle"
|
||||||
</Button>
|
:aria-label="t('components.audio.Player.label.shuffleQueue')"
|
||||||
</template>
|
@click.prevent.stop="shuffle()"
|
||||||
</Modal>
|
>
|
||||||
</Layout>
|
{{ t('components.audio.Player.label.shuffleQueue') }}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
v-if="store.state.auth.profile && playlist.actor.full_username === store.state.auth.fullUsername"
|
||||||
|
secondary
|
||||||
|
icon="bi-pencil"
|
||||||
|
@click="edit = !edit"
|
||||||
|
>
|
||||||
|
<template v-if="edit">
|
||||||
|
{{ t('views.playlists.Detail.button.stopEdit') }}
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ t('views.playlists.Detail.button.edit') }}
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
<Spacer
|
||||||
|
h
|
||||||
|
grow
|
||||||
|
/>
|
||||||
|
<playlist-dropdown
|
||||||
|
:playlist="playlist"
|
||||||
|
@import="fetchData"
|
||||||
|
/>
|
||||||
|
</Layout>
|
||||||
|
</Header>
|
||||||
|
|
||||||
<Layout stack>
|
<Layout stack>
|
||||||
<template v-if="edit">
|
<template v-if="edit">
|
||||||
|
@ -280,6 +258,26 @@ const deletePlaylist = async () => {
|
||||||
</Button>
|
</Button>
|
||||||
</Alert>
|
</Alert>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
v-if="playlist?.privacy_level === 'everyone' && playlist?.is_playable"
|
||||||
|
v-model="showEmbedModal"
|
||||||
|
title="t('views.playlists.Detail.modal.embed.header')"
|
||||||
|
>
|
||||||
|
<div class="scrolling content">
|
||||||
|
<div class="description">
|
||||||
|
<embed-wizard
|
||||||
|
:id="playlist.id"
|
||||||
|
type="playlist"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #actions>
|
||||||
|
<Button variant="outline">
|
||||||
|
{{ t('views.playlists.Detail.button.cancel') }}
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
</Layout>
|
</Layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue