sepia-search-motore-di-rice.../client/src/components/PlaylistResult.vue

218 lines
5.3 KiB
Vue

<template>
<div class="playlist search-card-result">
<div class="image-container">
<a class="img" :title="watchMessage" target="_blank" rel="nofollow noreferrer noopener" :href="playlist.url">
<img :src="playlist.thumbnailUrl" alt="" :class="{ error: thumbnailError }" @error="setThumbnailError()">
<div class="behind-1"></div>
<div class="behind-2"></div>
<div class="behind-3"></div>
<span class="videos-length">
<svg width="10" height="13" viewBox="0 0 10 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.47955e-05 6.26032V0L4.75 3.13016L2.47955e-05 6.26032Z" fill="#212529" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.47955e-05 12.5206V6.26025L4.75 9.39041L2.47955e-05 12.5206Z" fill="#212529" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.75002 9.39045V3.13013L9.5 6.26029L4.75002 9.39045Z" fill="#212529" />
</svg>
{{ videosLengthLabel }}
</span>
</a>
</div>
<div class="flex-grow-1">
<h4>
<strong>
<a class="wrap-text" :title="watchMessage" target="_blank" rel="nofollow noreferrer noopener" :href="playlist.url">
{{ playlist.displayName }}
</a>
</strong>
</h4>
<div class="small-separator mb-3"></div>
<!-- eslint-disable vue/no-v-html -->
<div
class="description wrap-text mb-3"
v-html="descriptionHTML"
/>
<!-- eslint-enable -->
<div class="metadata">
<div>
<label>{{ $gettext('Created by') }}</label>
<ActorMiniature type="account" :actor="playlist.ownerAccount" />
<span class="secondary-color ms-1">{{ $gettext('and updated on') }}</span>
{{ updatedDate }}
</div>
<div>
<label>{{ $gettext('In channel') }}</label>
<ActorMiniature type="channel" :actor="playlist.videoChannel" />
</div>
<div class="mb-3">
<label>{{ $gettext('On platform') }}</label>
<a class="peertube-link" target="_blank" rel="nofollow noreferrer noopener" :href="platformUrl">{{ host }}</a>
</div>
</div>
<div class="button-link-container">
<a class="peertube-button peertube-primary-button peertube-button-link" target="_blank" rel="nofollow noreferrer noopener" :href="playlist.url">
{{ watchMessage }}
</a>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import ActorMiniature from './ActorMiniature.vue'
export default defineComponent({
components: {
ActorMiniature
},
props: {
playlist: Object
},
data () {
return {
thumbnailError: false,
descriptionHTML: ''
}
},
computed: {
host () {
const url = this.playlist.url
return new URL(url).host
},
platformUrl () {
const url = this.playlist.url
const parsed = new URL(url)
return parsed.protocol + '//' + parsed.host
},
updatedDate () {
return new Date(this.playlist.updatedAt).toLocaleDateString()
},
watchMessage () {
return this.$gettext('Watch the playlist on %{host}', { host: this.host })
},
videosLengthLabel () {
return this.$ngettext('%{videosLength} video', '%{videosLength} videos', this.playlist.videosLength, { videosLength: this.playlist.videosLength })
}
},
mounted () {
this.lazyRenderMarkdown(this.playlist.description)
.then(html => this.descriptionHTML = html)
},
methods: {
setThumbnailError () {
this.thumbnailError = true
}
}
})
</script>
<style lang="scss" scoped>
@import '../scss/_variables';
.playlist {
.image-container {
// For the videos length overlay
.img {
position: relative;
display: inline-block;
}
.behind-1,
.behind-2,
.behind-3 {
position: absolute;
height: 100%;
width: 100%;
border-radius: 3px;
border: 1px solid $beige-700;
}
.behind-1 {
z-index: 3;
left: 8px;
width: calc(100% - 3px);
top: 5px;
background-color: $beige-400;
}
.behind-2 {
z-index: 2;
left: 14px;
width: calc(100% - 3px);
top: 11px;
background-color: $beige-500;
border: 1px solid $beige-700;
}
.behind-3 {
z-index: 1;
left: 20px;
width: calc(100% - 4px);
top: 17px;
background-color: $beige-700;
}
img {
width: 275px;
height: 147px;
border-radius: 3px;
position: relative;
z-index: 10;
&.error {
border: 1px solid #E5E5E5;
}
}
.videos-length {
font-size: 0.875rem;
position: absolute;
right: 0;
bottom: 0;
z-index: 15;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 15px;
height: 100%;
background-color: rgba($beige-800, 0.8);
font-weight: $font-semibold;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
}
}
</style>