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

195 lines
4.4 KiB
Vue

<template>
<div class="video search-card-result">
<div class="image-container">
<a class="img" :title="watchVideoMessage" target="_blank" rel="nofollow noreferrer noopener" :href="video.url">
<img :src="getVideoThumbnailUrl()" alt="" :class="{ error: thumbnailError }" @error="setThumbnailError()">
<span v-if="video.isLive" class="live-info">{{ $gettext('LIVE') }}</span>
<span v-else class="duration">{{ formattedDuration }}</span>
</a>
</div>
<div class="flex-grow-1">
<h4>
<strong>
<a class="wrap-text" :title="watchVideoMessage" target="_blank" rel="nofollow noreferrer noopener" :href="video.url">
{{ video.name }}
</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"
></div>
<!-- eslint-enable -->
<div class="metadata">
<div>
<label>{{ $gettext('Published by') }}</label>
<ActorMiniature type="account" :actor="video.account" />
<span class="secondary-color ms-1">on</span>
{{ publicationDate }}
</div>
<div>
<label>{{ $gettext('In channel') }}</label>
<ActorMiniature type="channel" :actor="video.channel" />
</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 v-if="video.language.id">
<label>{{ $gettext('Language:') }}</label>
<span>{{ video.language.label }}</span>
</div>
</div>
<div class="button-link-container">
<a
class="peertube-button peertube-primary-button peertube-button-link"
target="_blank"
rel="nofollow noreferrer noopener"
:href="video.url"
>
{{ watchVideoMessage }}
</a>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { durationToString } from '@/shared/utils'
import ActorMiniature from './ActorMiniature.vue'
export default defineComponent({
components: {
ActorMiniature
},
props: {
video: Object
},
data () {
return {
thumbnailError: false,
descriptionHTML: ''
}
},
computed: {
host () {
const url = this.video.url
return new URL(url).host
},
platformUrl () {
const url = this.video.url
const parsed = new URL(url)
return parsed.protocol + '//' + parsed.host
},
formattedDuration () {
return durationToString(this.video.duration)
},
windowWidth () {
return window.innerWidth
},
publicationDate () {
return new Date(this.video.publishedAt).toLocaleDateString()
},
watchVideoMessage () {
return this.$gettext('Watch the video on %{host}', { host: this.host })
}
},
mounted () {
this.lazyRenderMarkdown(this.video.description)
.then(html => this.descriptionHTML = html)
},
methods: {
getVideoThumbnailUrl () {
if (this.windowWidth >= 900) {
return this.video.thumbnailUrl
}
return this.video.previewUrl
},
setThumbnailError () {
this.thumbnailError = true
}
}
})
</script>
<style lang="scss" scoped>
@import '../scss/_variables';
.video {
.image-container {
// For the duration overlay
.img {
position: relative;
display: inline-block;
}
img {
background-color: #E5E5E5;
width: 275px;
height: 147px;
border-radius: 2px;
box-shadow: 4px 4px 0 0 $beige-700;
&.error {
border: 1px solid #E5E5E5;
}
}
.duration,
.live-info {
position: absolute;
display: inline-block;
padding: 2px 5px;
right: 0;
bottom: 0;
color: #fff;
background-color: #000;
font-size: 0.75rem;
border-radius: 2px 0px 0px 0px;
}
.duration {
background-color: rgba(0, 0, 0, 0.7);
}
.live-info {
background-color: rgba(224, 8, 8 ,.8);
font-weight: $font-semibold;
}
}
}
</style>