|
@@ -0,0 +1,252 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, PropType, computed } from "vue";
|
|
|
+import utils from "@/utils";
|
|
|
+import { RecordingTemp, ReleaseGroupTemp } from "@/types/artist";
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ recording: {
|
|
|
+ type: Object as PropType<RecordingTemp>,
|
|
|
+ required: true,
|
|
|
+ default: () => ({})
|
|
|
+ },
|
|
|
+ recordingImage: { type: String, required: true, default: "" },
|
|
|
+ containerClass: { type: String, default: "" },
|
|
|
+ enableReleaseGroups: { type: Boolean, default: false },
|
|
|
+ releaseGroupIds: { type: Array as PropType<string[]>, default: () => [] },
|
|
|
+ releaseGroupMap: {
|
|
|
+ type: Object as PropType<{
|
|
|
+ [releaseGroupId: string]: ReleaseGroupTemp;
|
|
|
+ }>,
|
|
|
+ default: () => {}
|
|
|
+ },
|
|
|
+ releaseGroupImageMap: { type: Object, default: () => ({}) },
|
|
|
+ hideMusicbrainzInfo: { type: Boolean, default: true }
|
|
|
+});
|
|
|
+
|
|
|
+// const emit = defineEmits(["clicked"]);
|
|
|
+
|
|
|
+const showRecordingReleaseGroup = ref(false);
|
|
|
+
|
|
|
+const releaseGroups = computed(() =>
|
|
|
+ props.releaseGroupIds.map(
|
|
|
+ releaseGroupId => props.releaseGroupMap[releaseGroupId]
|
|
|
+ )
|
|
|
+);
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="recording-container flex flex-column" :class="containerClass">
|
|
|
+ <div class="recording flex flex-row">
|
|
|
+ <slot name="top-left-pill"></slot>
|
|
|
+ <img
|
|
|
+ class="recording-image"
|
|
|
+ height="48"
|
|
|
+ width="48"
|
|
|
+ loading="lazy"
|
|
|
+ :src="recordingImage"
|
|
|
+ alt="Cover art"
|
|
|
+ onerror="this.src='/assets/notes.png'"
|
|
|
+ @click="showRecordingReleaseGroup = !showRecordingReleaseGroup"
|
|
|
+ />
|
|
|
+ <i v-if="recording.video" class="material-icons">smart_display</i>
|
|
|
+ <p>
|
|
|
+ <a
|
|
|
+ :href="`https://musicbrainz.org/recording/${recording.id}`"
|
|
|
+ target="_blank"
|
|
|
+ >
|
|
|
+ <span>{{ recording.title }}</span>
|
|
|
+ <span v-if="recording.disambiguation"
|
|
|
+ >({{ recording.disambiguation }})</span
|
|
|
+ >
|
|
|
+ </a>
|
|
|
+ <!-- <span>
|
|
|
+ <a
|
|
|
+ v-for="artistCredit in recording[
|
|
|
+ 'artist-credit'
|
|
|
+ ]"
|
|
|
+ :key="artistCredit.artist.id"
|
|
|
+ :href="`https://musicbrainz.org/artist/${artistCredit.artist.id}`"
|
|
|
+ target="_blank"
|
|
|
+ >
|
|
|
+ {{ artistCredit.name }}
|
|
|
+ </a>
|
|
|
+ </span> -->
|
|
|
+ </p>
|
|
|
+ <span>{{ utils.formatTime(recording.length / 1000) }}</span>
|
|
|
+ <div class="icons">
|
|
|
+ <tippy theme="info" v-if="!hideMusicbrainzInfo">
|
|
|
+ <i class="material-icons">info</i>
|
|
|
+
|
|
|
+ <template #content>
|
|
|
+ <div>
|
|
|
+ <ul>
|
|
|
+ <li>
|
|
|
+ <p>
|
|
|
+ Title:
|
|
|
+ {{ recording.title }}
|
|
|
+ </p>
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ <p>
|
|
|
+ Video:
|
|
|
+ {{ recording.video ? "true" : "false" }}
|
|
|
+ </p>
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ <p>
|
|
|
+ ID:
|
|
|
+ {{ recording.id }}
|
|
|
+ </p>
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ <p>
|
|
|
+ Length:
|
|
|
+ {{ recording.length }}
|
|
|
+ </p>
|
|
|
+ </li>
|
|
|
+ <li v-if="recording.disambiguation">
|
|
|
+ <p>
|
|
|
+ Disambiguation:
|
|
|
+ {{ recording.disambiguation }}
|
|
|
+ </p>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </tippy>
|
|
|
+ <!-- <i class="material-icons" @click="noop()"
|
|
|
+ >lock_open</i
|
|
|
+ >
|
|
|
+ <i class="material-icons" @click="noop()"
|
|
|
+ >lock</i
|
|
|
+ > -->
|
|
|
+ <!-- <i
|
|
|
+ class="material-icons"
|
|
|
+ v-if="manualHideRecordingMap[recording.id] === undefined"
|
|
|
+ @click="emit('toggleHideRecording')"
|
|
|
+ >hdr_auto</i
|
|
|
+ >
|
|
|
+ <i
|
|
|
+ class="material-icons"
|
|
|
+ v-else-if="recordingHideMap[recording.id]"
|
|
|
+ @click="emit('toggleHideRecording')"
|
|
|
+ >visibility_off</i
|
|
|
+ >
|
|
|
+ <i
|
|
|
+ class="material-icons"
|
|
|
+ v-else-if="!recordingHideMap[recording.id]"
|
|
|
+ @click="emit('toggleHideRecording')"
|
|
|
+ >visibility</i
|
|
|
+ > -->
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="release-groups flex flex-column"
|
|
|
+ v-if="enableReleaseGroups && showRecordingReleaseGroup"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="release-group flex flex-row"
|
|
|
+ v-if="releaseGroups.length === 0"
|
|
|
+ >
|
|
|
+ <p>No release groups</p>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="release-group flex flex-row"
|
|
|
+ v-for="releaseGroup in releaseGroups"
|
|
|
+ :key="releaseGroup.id"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ class="release-group-image"
|
|
|
+ height="32"
|
|
|
+ width="32"
|
|
|
+ loading="lazy"
|
|
|
+ :src="releaseGroupImageMap[releaseGroup.id]"
|
|
|
+ alt="Cover art"
|
|
|
+ onerror="this.src='/assets/notes.png'"
|
|
|
+ />
|
|
|
+ <p class="flex flex-column">
|
|
|
+ <a
|
|
|
+ :href="`https://musicbrainz.org/release-group/${releaseGroup.id}`"
|
|
|
+ target="_blank"
|
|
|
+ >
|
|
|
+ {{ releaseGroup.title }}
|
|
|
+ <span v-if="releaseGroup.disambiguation"
|
|
|
+ >({{ releaseGroup.disambiguation }})</span
|
|
|
+ >
|
|
|
+ </a>
|
|
|
+ <span>
|
|
|
+ {{
|
|
|
+ [
|
|
|
+ releaseGroup["primary-type"],
|
|
|
+ ...releaseGroup["secondary-types"]
|
|
|
+ ].join(" + ")
|
|
|
+ }}
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.flex {
|
|
|
+ display: flex;
|
|
|
+}
|
|
|
+
|
|
|
+.flex-column {
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.flex-row {
|
|
|
+ flex-direction: row;
|
|
|
+}
|
|
|
+
|
|
|
+.w-full {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.recording-container {
|
|
|
+ background-color: var(--dark-grey-2);
|
|
|
+ border-radius: @border-radius;
|
|
|
+ padding: 8px;
|
|
|
+ font-size: 16px;
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ .recording {
|
|
|
+ gap: 8px;
|
|
|
+ align-items: center;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .recording-image {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ > p {
|
|
|
+ flex: 1;
|
|
|
+ // gap: 4px;
|
|
|
+
|
|
|
+ a {
|
|
|
+ display: inline-flex;
|
|
|
+ flex-direction: column;
|
|
|
+ line-height: 24px;
|
|
|
+
|
|
|
+ span:nth-child(2) {
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .release-groups {
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ .release-group {
|
|
|
+ gap: 8px;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|