forked from DebaucheryLibrarian/traxxx
				
			
		
			
				
	
	
		
			300 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			300 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
| <template>
 | |
| 	<div
 | |
| 		:id="`${release.type}-${release.id}`"
 | |
| 		:class="{ new: release.isNew }"
 | |
| 		class="tile"
 | |
| 	>
 | |
| 		<span class="poster">
 | |
| 			<a
 | |
| 				:href="`/scene/${release.id}/${release.slug}`"
 | |
| 				target="_blank"
 | |
| 				rel="noopener noreferrer"
 | |
| 				class="link"
 | |
| 			>
 | |
| 				<img
 | |
| 					v-if="release.poster"
 | |
| 					:data-src="sfw ? `/img/${release.poster.sfw.thumbnail}` : `/media/${release.poster.thumbnail}`"
 | |
| 					:data-loading="sfw ? `/img/${release.poster.sfw.lazy}` : `/media/${release.poster.lazy}`"
 | |
| 					:alt="release.title"
 | |
| 					class="thumbnail"
 | |
| 				>
 | |
| 
 | |
| 				<span
 | |
| 					v-else-if="release.covers && release.covers.length > 0"
 | |
| 					class="covers"
 | |
| 				>
 | |
| 					<img
 | |
| 						v-for="cover in release.covers"
 | |
| 						:key="cover.id"
 | |
| 						:data-src="sfw ? `/img/${cover.sfw.thumbnail}` : `/media/${cover.thumbnail}`"
 | |
| 						:data-loading="sfw ? `/img/${cover.sfw.lazy}` : `/media/${cover.lazy}`"
 | |
| 						:alt="release.title"
 | |
| 						class="thumbnail cover"
 | |
| 					>
 | |
| 				</span>
 | |
| 
 | |
| 				<div
 | |
| 					v-else
 | |
| 					:title="release.title"
 | |
| 					class="thumbnail"
 | |
| 				>No thumbnail available</div>
 | |
| 			</a>
 | |
| 
 | |
| 			<Details :release="release" />
 | |
| 		</span>
 | |
| 
 | |
| 		<div class="info">
 | |
| 			<a
 | |
| 				:href="`/scene/${release.id}/${release.slug}`"
 | |
| 				target="_blank"
 | |
| 				rel="noopener noreferrer"
 | |
| 				class="row link"
 | |
| 			>
 | |
| 				<h3
 | |
| 					v-if="release.title"
 | |
| 					v-tooltip.bottom="release.title"
 | |
| 					:title="release.title"
 | |
| 					class="title"
 | |
| 				>{{ release.title }}</h3>
 | |
| 
 | |
| 				<h3
 | |
| 					v-else-if="release.actors.length > 0"
 | |
| 					class="title title-composed"
 | |
| 				>{{ release.actors[0].name }} for {{ release.entity.name }}</h3>
 | |
| 
 | |
| 				<h3
 | |
| 					v-else
 | |
| 					class="title title-empty"
 | |
| 				>{{ release.entity.name }}</h3>
 | |
| 			</a>
 | |
| 
 | |
| 			<span class="row">
 | |
| 				<ul
 | |
| 					class="actors nolist"
 | |
| 					:title="release.actors.map(actor => actor.name).join(', ')"
 | |
| 				>
 | |
| 					<li
 | |
| 						v-for="actor in release.actors"
 | |
| 						:key="actor.id"
 | |
| 						class="actor"
 | |
| 					>
 | |
| 						<router-link
 | |
| 							:to="{ name: 'actor', params: { actorId: actor.id, actorSlug: actor.slug } }"
 | |
| 							class="actor-link"
 | |
| 						>{{ actor.name }}</router-link>
 | |
| 					</li>
 | |
| 				</ul>
 | |
| 			</span>
 | |
| 
 | |
| 			<div class="labels">
 | |
| 				<router-link
 | |
| 					v-if="release.shootId && release.studio"
 | |
| 					:to="{ name: 'studio', params: { entitySlug: release.studio.slug } }"
 | |
| 					:title="release.studio && release.studio.name"
 | |
| 					class="shoot nolink"
 | |
| 				>{{ release.shootId }}</router-link>
 | |
| 
 | |
| 				<span
 | |
| 					v-else-if="release.shootId"
 | |
| 					:title="release.studio && release.studio.name"
 | |
| 					class="shoot nolink"
 | |
| 				>{{ release.shootId }}</span>
 | |
| 
 | |
| 				<ul
 | |
| 					v-if="release.tags.length > 0"
 | |
| 					:title="release.tags.map(tag => tag.name).join(', ')"
 | |
| 					class="tags nolist"
 | |
| 				>
 | |
| 					<li
 | |
| 						v-for="tag in release.tags"
 | |
| 						:key="`tag-${tag.slug}`"
 | |
| 						class="tag"
 | |
| 					>
 | |
| 						<router-link
 | |
| 							:to="`/tag/${tag.slug}`"
 | |
| 							class="tag-link"
 | |
| 						>{{ tag.name }}</router-link>
 | |
| 					</li>
 | |
| 				</ul>
 | |
| 			</div>
 | |
| 		</div>
 | |
| 	</div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import Details from './tile-details.vue';
 | |
| 
 | |
| function sfw() {
 | |
| 	return this.$store.state.ui.sfw;
 | |
| }
 | |
| 
 | |
| export default {
 | |
| 	components: {
 | |
| 		Details,
 | |
| 	},
 | |
| 	props: {
 | |
| 		release: {
 | |
| 			type: Object,
 | |
| 			default: null,
 | |
| 		},
 | |
| 	},
 | |
| 	computed: {
 | |
| 		sfw,
 | |
| 	},
 | |
| };
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| @import 'theme';
 | |
| 
 | |
| .tile {
 | |
|     background: var(--background);
 | |
|     display: flex;
 | |
|     flex-direction: column;
 | |
|     box-sizing: border-box;
 | |
|     overflow: hidden;
 | |
|     box-shadow: 0 0 3px var(--darken-weak);
 | |
|     height: 100%;
 | |
| 
 | |
| 	&.new .poster::after {
 | |
| 		content: 'new';
 | |
| 		position: absolute;
 | |
| 		top: 0;
 | |
| 		right: 0;
 | |
| 		padding: .15rem .25rem .15rem .35rem;
 | |
| 		border-radius: 0 0 0 .5rem;
 | |
| 		color: var(--text-light);
 | |
| 		background: var(--primary);
 | |
| 		font-size: .8rem;
 | |
| 		font-weight: bold;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| .poster {
 | |
|     position: relative;
 | |
|     margin: 0 0 .6rem 0;
 | |
| }
 | |
| 
 | |
| .covers {
 | |
|     background: var(--profile);
 | |
|     display: flex;
 | |
| 
 | |
|     .cover {
 | |
|         width: 50%;
 | |
|     }
 | |
| }
 | |
| 
 | |
| .thumbnail {
 | |
|     width: 100%;
 | |
|     height: 14rem;
 | |
|     display: flex;
 | |
|     justify-content: center;
 | |
|     align-items: center;
 | |
|     object-fit: cover;
 | |
|     background-position: center;
 | |
|     background-size: cover;
 | |
|     background-color: var(--shadow-hint);
 | |
|     color: var(--shadow);
 | |
|     text-shadow: 1px 1px 0 var(--highlight);
 | |
| }
 | |
| 
 | |
| .row {
 | |
|     display: flex;
 | |
|     justify-content: space-between;
 | |
|     align-items: center;
 | |
|     box-sizing: border-box;
 | |
|     padding: 0 .5rem;
 | |
|     margin: 0 0 .25rem 0;
 | |
| }
 | |
| 
 | |
| .info {
 | |
|     display: flex;
 | |
|     flex-direction: column;
 | |
|     flex-grow: 1;
 | |
| }
 | |
| 
 | |
| .link {
 | |
|     text-decoration: none;
 | |
| }
 | |
| 
 | |
| .title {
 | |
|     margin: 0;
 | |
|     color: var(--text);
 | |
|     font-size: 1rem;
 | |
|     line-height: 1.5;
 | |
| 	white-space: nowrap;
 | |
|     text-overflow: ellipsis;
 | |
|     overflow: hidden;
 | |
| }
 | |
| 
 | |
| .title-composed,
 | |
| .title-empty {
 | |
| 	color: var(--shadow);
 | |
| }
 | |
| 
 | |
| .actors {
 | |
|     word-wrap: break-word;
 | |
|     overflow: hidden;
 | |
|     max-height: 1.5rem;
 | |
|     line-height: 1.5rem;
 | |
| 	margin: 0 0 .25rem 0;
 | |
| }
 | |
| 
 | |
| .actor:not(:last-of-type)::after {
 | |
|     content: ",";
 | |
| 	margin: 0 .25rem 0 0;
 | |
| }
 | |
| 
 | |
| .actor-link {
 | |
|     color: var(--link);
 | |
|     text-decoration: none;
 | |
| 
 | |
|     &:hover {
 | |
|         color: var(--primary);
 | |
|     }
 | |
| }
 | |
| 
 | |
| .labels {
 | |
|     padding: .1rem .5rem 1.5rem .5rem;
 | |
|     max-height: .5rem;
 | |
|     overflow-y: hidden;
 | |
| 	font-size: 0;
 | |
|     line-height: 2;
 | |
| }
 | |
| 
 | |
| .shoot {
 | |
| 	display: inline;
 | |
| 	padding: .25rem .5rem;
 | |
| 	background: var(--primary);
 | |
| 	color: var(--text-light);
 | |
| 	font-size: 0.75rem;
 | |
| 	font-weight: bold;
 | |
| 	box-shadow: inset 0 0 3px var(--shadow-weak);
 | |
| }
 | |
| 
 | |
| .tags {
 | |
| 	display: inline;
 | |
|     word-wrap: break-word;
 | |
| }
 | |
| 
 | |
| .tag {
 | |
|     margin: 0 0 1rem 0;
 | |
| }
 | |
| 
 | |
| .tag-link {
 | |
| 	background: var(--background);
 | |
|     color: var(--shadow);
 | |
|     display: inline-block;
 | |
|     padding: .25rem .5rem;
 | |
|     font-size: .75rem;
 | |
|     font-weight: bold;
 | |
|     text-decoration: none;
 | |
|     line-height: 1;
 | |
| 	box-shadow: 0 0 3px var(--shadow-weak);
 | |
| 
 | |
|     &:hover {
 | |
|         color: var(--primary);
 | |
|     }
 | |
| }
 | |
| </style>
 |