funkwhale/front/src/components/library/TrackDetail.vue

282 wiersze
9.9 KiB
Vue
Czysty Zwykły widok Historia

2022-08-08 22:39:59 +00:00
<script setup lang="ts">
2022-08-31 18:43:25 +00:00
import type { Track, Library } from '~/types'
2022-08-08 22:39:59 +00:00
import { humanSize, momentFormat, truncate } from '~/utils/filters'
import { computed, ref, watchEffect } from 'vue'
import time from '~/utils/time'
import axios from 'axios'
import LibraryWidget from '~/components/federation/LibraryWidget.vue'
import PlaylistWidget from '~/components/playlists/Widget.vue'
import TagsList from '~/components/tags/List.vue'
import useErrorHandler from '~/composables/useErrorHandler'
2022-08-31 18:43:25 +00:00
interface Events {
(e: 'libraries-loaded', libraries: Library[]): void
}
2022-08-08 22:39:59 +00:00
interface Props {
track: Track
}
2022-08-31 18:43:25 +00:00
const emit = defineEmits<Events>()
2022-08-08 22:39:59 +00:00
const props = defineProps<Props>()
const musicbrainzUrl = computed(() => props.track.mbid
? `https://musicbrainz.org/recording/${props.track.mbid}`
: null
)
const upload = computed(() => props.track.uploads?.[0] ?? null)
const license = ref()
const fetchLicense = async (licenseId: string) => {
license.value = undefined
try {
const response = await axios.get(`licenses/${licenseId}`)
license.value = response.data
} catch (error) {
useErrorHandler(error as Error)
2022-08-08 22:39:59 +00:00
}
}
watchEffect(() => {
if (props.track.license) {
// @ts-expect-error For some reason, track.license is id instead of License here
fetchLicense(props.track.license)
}
})
</script>
<template>
<div v-if="track">
<section class="ui vertical stripe segment">
2020-03-26 15:18:37 +00:00
<div class="ui stackable grid row container">
<div class="six wide column">
<template v-if="upload">
2021-12-06 10:35:20 +00:00
<img
v-if="track.cover && track.cover.urls.large_square_crop"
v-lazy="$store.getters['instance/absoluteUrl'](track.cover.urls.large_square_crop)"
alt="Cover Image"
class="ui fluid image track-cover-image"
>
<img
2022-02-10 12:31:32 +00:00
v-else-if="track.album && track.album.cover && track.album.cover.urls.large_square_crop"
2021-12-06 10:35:20 +00:00
v-lazy="$store.getters['instance/absoluteUrl'](track.album.cover.urls.large_square_crop)"
alt="Cover Image"
class="ui fluid image track-cover-image"
>
2022-02-10 12:31:32 +00:00
<img
2022-02-10 12:36:20 +00:00
v-else
2022-02-10 18:30:26 +00:00
src="../../assets/audio/default-cover.png"
2022-02-10 12:36:20 +00:00
alt="Cover Image"
class="ui fluid image track-cover-image"
2022-02-10 12:31:32 +00:00
>
2020-03-26 15:18:37 +00:00
<h3 class="ui header">
2022-11-26 23:16:46 +00:00
<span v-if="track.artist?.content_category === 'music'">
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.header.track') }}
2022-09-17 02:14:35 +00:00
</span>
2022-11-26 23:16:46 +00:00
<span v-else>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.header.episode') }}
2022-09-17 02:14:35 +00:00
</span>
2020-03-26 15:18:37 +00:00
</h3>
<table class="ui basic table">
<tbody>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.track.duration') }}
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
2021-12-06 10:35:20 +00:00
<template v-if="upload.duration">
2022-04-30 20:46:37 +00:00
{{ time.parse(upload.duration) }}
2021-12-06 10:35:20 +00:00
</template>
2022-11-26 23:16:46 +00:00
<span v-else>
2022-09-17 02:14:35 +00:00
{{ $t('components.library.TrackDetail.notApplicable') }}
</span>
2020-03-26 15:18:37 +00:00
</td>
</tr>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.track.size') }}
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
2021-12-06 10:35:20 +00:00
<template v-if="upload.size">
2022-04-30 20:46:37 +00:00
{{ humanSize(upload.size) }}
2021-12-06 10:35:20 +00:00
</template>
2022-11-26 23:16:46 +00:00
<span v-else>
2022-09-17 02:14:35 +00:00
{{ $t('components.library.TrackDetail.notApplicable') }}
</span>
2020-03-26 15:18:37 +00:00
</td>
</tr>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.track.codec') }}
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
2021-12-06 10:35:20 +00:00
<template v-if="upload.extension">
{{ upload.extension }}
</template>
2022-11-26 23:16:46 +00:00
<span v-else>
2022-09-17 02:14:35 +00:00
{{ $t('components.library.TrackDetail.notApplicable') }}
</span>
2020-03-26 15:18:37 +00:00
</td>
</tr>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.track.bitrate.label') }}
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
2021-12-06 10:35:20 +00:00
<template v-if="upload.bitrate">
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.track.bitrate.value', {bitrate: humanSize(upload.bitrate)}) }}
2021-12-06 10:35:20 +00:00
</template>
2022-11-26 23:16:46 +00:00
<span v-else>
2022-09-17 02:14:35 +00:00
{{ $t('components.library.TrackDetail.notApplicable') }}
</span>
2020-03-26 15:18:37 +00:00
</td>
</tr>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.track.downloads') }}
</td>
<td class="right aligned">
{{ track.downloads_count }}
</td>
</tr>
2020-03-26 15:18:37 +00:00
</tbody>
</table>
</template>
</div>
<div class="ten wide column">
<template v-if="track.tags && track.tags.length > 0">
2021-12-06 10:35:20 +00:00
<tags-list :tags="track.tags" />
<div class="ui hidden divider" />
2020-03-26 15:18:37 +00:00
</template>
<rendered-description
:content="track.description"
2021-12-06 10:35:20 +00:00
:can-update="false"
/>
2020-03-26 15:18:37 +00:00
<h2 class="ui header">
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.header.release') }}
2020-03-26 15:18:37 +00:00
</h2>
<table class="ui basic table ellipsis-rows">
<tbody>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.release.artist') }}
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
2022-08-08 22:39:59 +00:00
<router-link :to="{name: 'library.artists.detail', params: {id: track.artist?.id}}">
{{ track.artist?.name }}
2020-03-26 15:18:37 +00:00
</router-link>
</td>
</tr>
<tr v-if="track.album">
<td>
2022-11-26 23:16:46 +00:00
<span v-if="track.album.artist.content_category === 'music'">
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.release.album') }}
2022-09-17 02:14:35 +00:00
</span>
2022-11-26 23:16:46 +00:00
<span v-else>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.release.series') }}
2022-09-17 02:14:35 +00:00
</span>
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
<router-link :to="{name: 'library.albums.detail', params: {id: track.album.id}}">
{{ track.album.title }}
</router-link>
</td>
</tr>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.release.year') }}
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
<template v-if="track.album && track.album.release_date">
2022-08-08 22:39:59 +00:00
{{ momentFormat(new Date(track.album.release_date), 'Y') }}
2020-03-26 15:18:37 +00:00
</template>
<template v-else>
2022-09-17 02:14:35 +00:00
{{ $t('components.library.TrackDetail.notApplicable') }}
2020-03-26 15:18:37 +00:00
</template>
</td>
</tr>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.release.copyright') }}
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
2021-12-06 10:35:20 +00:00
<span
v-if="track.copyright"
:title="track.copyright"
2022-04-30 20:46:37 +00:00
>{{ truncate(track.copyright, 50) }}</span>
2020-03-26 15:18:37 +00:00
<template v-else>
2022-09-17 02:14:35 +00:00
{{ $t('components.library.TrackDetail.notApplicable') }}
2020-03-26 15:18:37 +00:00
</template>
</td>
</tr>
<tr>
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.release.license') }}
2020-03-26 15:18:37 +00:00
</td>
<td class="right aligned">
2021-12-06 10:35:20 +00:00
<a
v-if="license"
:href="license.url"
target="_blank"
rel="noopener noreferrer"
>{{ license.name }}</a>
2022-11-26 23:16:46 +00:00
<span v-else>
2022-09-17 02:14:35 +00:00
{{ $t('components.library.TrackDetail.notApplicable') }}
</span>
2020-03-26 15:18:37 +00:00
</td>
</tr>
<tr v-if="!track.is_local">
<td>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.table.release.url') }}
2020-03-26 15:18:37 +00:00
</td>
<td :title="track.fid">
2021-12-06 10:35:20 +00:00
<a
:href="track.fid"
target="_blank"
rel="noopener noreferrer"
>
2022-04-30 20:46:37 +00:00
{{ truncate(track.fid, 65) }}
2020-03-26 15:18:37 +00:00
</a>
</td>
</tr>
</tbody>
</table>
2021-12-06 10:35:20 +00:00
<a
v-if="musicbrainzUrl"
:href="musicbrainzUrl"
target="_blank"
rel="noreferrer noopener"
>
<i class="external icon" />
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.link.musicbrainz') }}
2020-03-26 15:18:37 +00:00
</a>
<h2 class="ui header">
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.header.playlists') }}
2020-03-26 15:18:37 +00:00
</h2>
2021-12-06 10:35:20 +00:00
<playlist-widget
:url="'playlists/'"
:filters="{track: track.id, playable: true, ordering: '-modification_date'}"
/>
2020-03-26 15:18:37 +00:00
<h2 class="ui header">
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.header.library') }}
2020-03-26 15:18:37 +00:00
</h2>
2021-12-06 10:35:20 +00:00
<library-widget
2022-08-08 22:39:59 +00:00
:url="`tracks/${track.id}/libraries/`"
2022-08-31 18:43:25 +00:00
@loaded="emit('libraries-loaded', $event)"
2021-12-06 10:35:20 +00:00
>
2022-09-22 23:26:59 +00:00
{{ $t('components.library.TrackDetail.description.library') }}
2020-03-26 15:18:37 +00:00
</library-widget>
</div>
</div>
</section>
</div>
</template>